clojure - Using LevelDB in a ring/compojure webapp -


i am trying setup leveldb in ring/compojure app, , looking idiomatic way to access opened db descriptor each request.

for example:

(defn -main   "i don't 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}))) 

how access main-db descriptor request handlers?

ie.:

(defroutes handler    (get "/test" []     (db/put main-db (.getbytes "testkey2") (.getbytes "testvalue2"))     "<h1>hello world</h1>") 

ps: using leveldb-clj lib sedward , packaged clojar: https://clojars.org/org.clojars.aircart/leveldb-clj

if want single global descriptor in app, simplest option might store promise or delay in top-level var:

(def level-db-descriptor (promise))  (defn open [...]   ...   (deliver level-db-descriptor ...))  (open ...)  ;; or  (def level-db-descriptor (delay (open ...))) 

then @level-db-descriptor when need @ it.

this not great if need replace descriptor occasionally; can, however, support while preserving @level-db-descriptor pattern of usage:

(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           (.-val box)))       (put-descriptor! [this d]         (locking           (set! (.-val box) d)))))) 

you replace put-descriptor! more sophisticated, of course (perhaps producing new descriptor after doing old one).

if want able run multiple instances of app in parallel, individual instances use sort of state containers , you'll want use store descriptors rather top-level vars.


Comments