在ring / compojure webapp中使用LevelDB

时间:2013-07-19 09:08:20

标签: clojure compojure ring leveldb

我正在尝试在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

1 个答案:

答案 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