2017-03-01 38 views
0

當我寫入到SQLite表中時,我用http-kit異步行爲進行了干預。異步clojure http-kit客戶端與回調寫入數據庫sqlite3

數據庫的I/O取決於我是將代碼發送到boot repl還是將其作爲boot腳本運行。 I/O只能在repl情況下進行。我錯過了什麼?這是我的代碼:

#!/usr/bin/env boot                                    

(defn deps [new-deps]                                   
    (boot.core/merge-env! :dependencies new-deps))                             

(deps '[                                       
     [http-kit "2.2.0"]                           
     [org.clojure/core.async "0.2.395"]                              
     [org.clojure/java.jdbc "0.7.0-alpha1"]                             
     [org.xerial/sqlite-jdbc "3.16.1"]                              
     [org.slf4j/slf4j-nop "1.7.22"]                               
     ])                                      

(require                                       
     '[org.httpkit.client :as http]                               
     '[clojure.java.jdbc :as jdbc]                               
     )                                      


(def db-spec                                      
    {:classname "org.sqlite.JDBC"                                 
    :subprotocol "sqlite"                                   
    :subname "sqlite.db"})                                  

;(jdbc/db-do-commands                                   
    ;db-spec                                      
    ;(jdbc/create-table-ddl "test" [[:msg :text]]))                            

(def ins! (partial jdbc/insert! db-spec "test"))                             

(http/get "http://locahost" {} (fn [_] (ins! {:msg "repl"})))                         


(defn -main []                                     
    (println (System/getProperty "user.dir"))                              
    (http/get "http://locahost" {} (fn [_] (ins! {:msg "exec"}))))                         

感謝

+1

能否請你解決你的問題,因爲它沒有按」工作?它有幾個問題:它缺少clojure.java.jdbc依賴關係,並指定了「web」依賴關係,這對您的問題並不重要,並且在公共maven回購站中不可用。 –

回答

1

與腳本沒有命令行工作的問題是,HTTP-KIT異步回調被daemon threads處理,唯一的非守護線程是主線程運行你的腳本。

如果-main函數在向http-kit提交HTTP請求以進行異步處理後結束,則主線程將終止並導致JVM在守護進程線程處理異步回調之前關閉,從而有機會運行。

您可以檢查在-main函數的末尾添加睡眠表情,看看你的回調執行:

(defn -main []                                     
    (println (System/getProperty "user.dir"))                              
    (http/get "http://locahost" {} (fn [_] (ins! {:msg "exec"}))) 
    (Thread/sleep 60000)) 

,以確保該-main功能將等待結果的最佳方式被處理的是保留通過http/get返回的承諾。該承諾最終將包含回調函數產生的結果是:

(let [result-promise (http/get "https://www.google.com" {} (fn [_] "Result"))] 
    @result-promise) 

@result-promise(deref result-promise)讀者宏/快捷方式。

完整形式可能會更好,當你想不無限期地阻塞 - 只需撥打deref與超時-MS和超時值參數:

(deref result-promise 5000 "Didn't get response in 5 seconds. Giving up")

+0

有沒有更清晰的方式來處理問題而不是使用睡眠? – user3639782

+1

我已更新我的答案以提供推薦的方法。 –