我正在尝试在ring / compojure应用程序中设置LevelDB,并寻找一种惯用的方法来访问每个请求中打开的数据库描述符。
例如:
(defn -main
"I don't do a whole lot ... yet."
[& args]
(println "Opening LevelDB file in db/main")
(with-open [main-db (db/open "db/main")]
(println "Running server on port 3000")
(run-jetty #'web/app {:port 3000})))
如何在请求处理程序中访问main-db
描述符?
即:
(defroutes handler
(GET "/test" []
(db/put main-db (.getBytes "testKey2") (.getBytes "testValue2"))
"<h1>Hello World</h1>")
PS:我正在使用Sedward的leveldb-clj lib并将其打包成clojar:https://clojars.org/org.clojars.aircart/leveldb-clj
答案 0 :(得分:0)
如果您想在应用中使用单个全局描述符,最简单的选项可能是在顶级Var中存储承诺或延迟:
(def level-db-descriptor (promise))
(defn open [...]
...
(deliver level-db-descriptor ...))
(open ...)
;; or
(def level-db-descriptor (delay (open ...)))
然后在需要时说出@level-db-descriptor
。
如果您需要偶尔替换描述符,这不是很好;但是,您也可以在保留@level-db-descriptor
使用模式的同时支持它:
(defprotocol PDescriptorBox
(put-descriptor! [this d])
(get-descriptor [this]))
(defn make-descriptor-box []
(let [box (clojure.lang.Box. nil)]
(reify
clojure.lang.IDeref
(deref [this] (get-descriptor this))
PDescriptorBox
(get-descriptor [this]
(locking this
(.-val box)))
(put-descriptor! [this d]
(locking this
(set! (.-val box) d))))))
当然,您可以用更复杂的东西替换put-descriptor!
(也许只有在使用旧的描述符之后才生成新的描述符)。
如果您希望能够并行运行应用程序的多个实例,那么这些单个实例可能会使用某种状态容器,您可能希望使用它们来存储描述符而不是顶级Vars