我正在创建一个代理,用于将更改写回数据库(如Clojure Programming中基于代理的后写日志中所述)。
这工作正常,但我很难创建代理。我不想将其创建为def,因为我不希望在我的测试运行时创建它(我看到当测试加载表单时池启动,即使我使用with-redefs来设置测试值。)
我开始使用的代码是(使用c3p0池):
(def dba (agent (pool/make-datasource-spec (u/load-config "db.edn"))))
我尝试将代理设为nil,并调查了如何在我的应用程序的主要部分设置它,当它真正需要时。但是,与原子相比,它似乎不是一个等价的reset!
函数。并且以下代码也未能说代理没有错误,因此不需要重新启动:
(when (not @dba)
(restart-agent dba (create-db-pool)))
所以目前,我有一个包含代理的原子,然后我会这样做:
(def dba (atom nil))
;; ...
(defn init-db! []
(when (not @dba)
(log/info "Creating agent for pooled connection")
(reset! dba (agent (create-db-pool))))
但是我必须@@dba
来引用代理的内容(即池),这让我觉得这很疯狂。
是否有更明显的方式来懒惰地创建池代理?
答案 0 :(得分:3)
delay
对于此类案例非常有用。它会在第一次读取时创建项目。因此,如果您的测试没有读取它,则不会创建它。
user=> (def my-agent (delay (do (println "im making the agent now") (agent 0))))
#'user/my-agent
user=>
user=> @my-agent
im making the agent now
#object[clojure.lang.Agent 0x2cd73ca1 {:status :ready, :val 0}]