我正在创建与elasticsearch的连接(但是替换您喜欢的任何其他数据源),它将基于运行时的环境或配置文件参数.它看起来像这样:
(defn create-conn
"Connect to the given uri. This is a persistent conn managed by clj-http (apache)."
([uri]
( ;;; create a persistent connection using clj-http / elastic
...)
([]
(create-conn (or (System/getenv "ES_URL")
(cfg/get-url-from-config-file)
"http://localhost:9200"))))
因为连接在服务器的生命周期内不会改变,所以我只需要运行一次这个函数并缓存结果.有几种方法可以做到这一点:
1 – 记住它 – 虽然这有效,但它感觉不是正确的方法,因为我只是缓存一件事
2 – 使用像Component或mount这样的状态管理器;因为我不是真正管理国家,只是设置和遗忘,而只是将它用于这一件事,感觉有点矫枉过正.例如,以下如何优于下面的#3?
; mount version -- good, but how is this better than #3 below?
(defstate conn :start (getconn))
(mount/start #'elastic/conn) ;; somewhere else, must start mount
3 – def it.即使运行create-conn实际上并没有执行任何网络活动,我宁愿不在文件加载时运行它,如果我只是对它进行常规def会发生什么,所以我必须做类似的事情以下…注意getconn函数是为了方便,所以我不必直接deref conn:
(def conn (delay (create-conn)))
(defn getconn [] @conn)
4 – 使用一个原子 – 直截了当,但这不是一个需要改变的var,它引入了一个不需要的状态:
(def conn (atom nil))
(def getconn []
(if-not @conn (reset! conn (create-conn)))
@conn)
5 – [在此插入您的想法]
在上面,我更喜欢3,因为它使用不可变数据,即使延迟有点笨重.您的偏好是什么,无论是来自上面的列表,还是您自己的解决方案?
最佳答案
Mount或
component正是为此而建造的 – 控制状态大多是固定的(有时需要更新连接). Mount是两个库中最简单的一个,允许您定义连接一次,并在需要的地方“需要”它.