Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 使用比较和集合的惰性计算_Mongodb_Concurrency_Clojure_Monger - Fatal编程技术网

Mongodb 使用比较和集合的惰性计算

Mongodb 使用比较和集合的惰性计算,mongodb,concurrency,clojure,monger,Mongodb,Concurrency,Clojure,Monger,我试图实现一个get database函数,该函数在第一次调用Monger时从Monger检索数据库引用,记住atom中的值,并在后续调用中直接返回该值。我当前的代码如下所示: (def database (atom nil)) (defn get-database [] (compare-and-set! database nil (let [db (:db (mg/connect-via-uri (System/getenv "MONGOLAB_URI")))] db))

我试图实现一个
get database
函数,该函数在第一次调用Monger时从Monger检索数据库引用,记住atom中的值,并在后续调用中直接返回该值。我当前的代码如下所示:

(def database (atom nil))

(defn get-database
  []
  (compare-and-set! database nil
    (let [db (:db (mg/connect-via-uri (System/getenv "MONGOLAB_URI")))] db))
  @database)

问题是,即使
比较并设置,
let
子句似乎也会被计算
返回false(即
数据库
不是
nil
)。是否有某种方法可以让它惰性地进行评估,这样我就不会因为检索Monger连接而受到惩罚,或者这种方法从根本上来说是错误的?

这里的问题是
比较并设置
是一个函数,因此对其求值将在调用函数之前对所有参数求值

对于缓存和重新使用一些昂贵的计算值的用例,我采用的典型方法是:

获取表达式体并生成一个延迟对象,该延迟对象将 仅在第一次强制时调用主体(使用force或deref/@),并且 将缓存结果并将其返回到所有后续强制 电话。参见-实现

就你而言:

(def database (delay (:db (mg/connect-via-uri (System/getenv "MONGOLAB_URI")))))

现在,只要在任何时候想获得对数据库的引用,就可以说
@database
,当代码第一次实际导致延迟被取消引用时,连接就会被初始化。如果愿意,可以在
get database
函数中包装调用以取消对延迟的引用,但这不是必需的。

这里的问题是
比较并设置
是一个函数,因此对其求值将在调用函数之前对所有参数求值

对于缓存和重新使用一些昂贵的计算值的用例,我采用的典型方法是:

获取表达式体并生成一个延迟对象,该延迟对象将 仅在第一次强制时调用主体(使用force或deref/@),并且 将缓存结果并将其返回到所有后续强制 电话。参见-实现

就你而言:

(def database (delay (:db (mg/connect-via-uri (System/getenv "MONGOLAB_URI")))))

现在,只要在任何时候想获得对数据库的引用,就可以说
@database
,当代码第一次实际导致延迟被取消引用时,连接就会被初始化。如果愿意,您可以在
get database
函数中包装调用以取消对延迟的引用,但这不是必需的。

Nice。所以我想在这种情况下,让
数据库
成为一个原子是多余的?延迟的使用是否保证不会出现竞争条件?正确。延迟实现是线程安全的,并保证主体只执行一次。当主体仍在执行时,尝试从其他线程取消对延迟的引用将一直阻塞,直到它完成。也许这需要一个单独的问题,但我仍然不完全清楚延迟的并发更新。在延迟解除引用后更改其值是否符合犹太教义?如果是这样,为什么必须使用
swap更新atom(或某些其他功能),但延迟没有任何等效功能?延迟只有两种状态:未实现(初始创建时)和已实现(一旦强制或取消引用)。一旦实现了延迟,它的值就永远不会改变,这似乎就是您在上面的示例代码中所追求的语义。没错。我试图将相同的构造用于另一个目的,但根据您的评论,这是不合适的,因为我在取消引用后更改了值。Nice。所以我想在这种情况下,让
数据库
成为一个原子是多余的?延迟的使用是否保证不会出现竞争条件?正确。延迟实现是线程安全的,并保证主体只执行一次。当主体仍在执行时,尝试从其他线程取消对延迟的引用将一直阻塞,直到它完成。也许这需要一个单独的问题,但我仍然不完全清楚延迟的并发更新。在延迟解除引用后更改其值是否符合犹太教义?如果是这样,为什么必须使用
swap更新atom(或某些其他功能),但延迟没有任何等效功能?延迟只有两种状态:未实现(初始创建时)和已实现(一旦强制或取消引用)。一旦实现了延迟,它的值就永远不会改变,这似乎就是您在上面的示例代码中所追求的语义。没错。我试图将同一构造用于另一个目的,但根据您的评论,这是不合适的,因为我在取消引用后更改了值。