2013-07-19 25 views
0

我正試圖在ring/compojure應用程序中設置LevelDB,並尋找一種慣用的方式來訪問每個請求中打開的數據庫描述符。在ring/compojure webapp中使用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:我使用的是性LevelDB-CLJ從Sedward lib和它包裝成一個clojar:https://clojars.org/org.clojars.aircart/leveldb-clj

回答

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!

如果你想能夠並行運行你的應用程序的多個實例,那麼這些單獨的實例可能會使用某種狀態容器,你可能想用它們來存儲描述符而不是頂級瓦爾。

+0

謝謝!我實際上通過定義一個將描述符作爲參數的函數來解決這個問題:'(run-jetty(web/load-with-descriptor main-db){:port 3000})))'並移動定義該函數內部的路由,以便在內部定義描述符。您是否會看到使用環形碼頭時遇到的任何問題?或者使用netty會更有意義? – user2598730