2017-03-01 4 views
0

sqliteテーブルへの書き込みには、http-kitの非同期動作があります。async clojureデータベースにコールバックを書き込むhttp-kitクライアントsqlite3

データベースへの入出力は、コードをbootに送信するか、bootスクリプトとして実行するかによって異なります。 i/oはreplの場合にのみ進行します。私は何が欠けていますか?ここに私のコードがs:スクリプトは、コマンドラインから動作していないと

#!/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

:ちょうどタイムアウト-MSおよびタイムアウト値の引数を持つderefを呼び出す - あなたは無期限にブロックされないしたいとき

完全な形式が良いかもしれません仕事は?これにはいくつかの問題があります:clojure.java.jdbcの依存関係が欠けていて、あなたの質問に必須ではなく、パブリックなリポジトリでは利用できない 'web'依存関係が指定されています。 –

答えて

1

問題は、http-キット非同期コールバックがdaemon threadsによって処理されることであり、唯一の非デーモンスレッドがメインスレッドですあなたのスクリプトを実行する。

HTTPリクエストをhttp-kitに非同期処理で送信した後で-main関数が終了すると、メインスレッドが終了し、非同期コールバックを処理するデーモンスレッドが実行される前に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)リーダマクロ/ショートカットです。それはdoesnのよう、あなたの質問を修正してもらえ

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

+0

は、睡眠を使用する代わりに問題を処理するためのクリーンな方法はありますか? – user3639782

+1

私は推奨アプローチを提供するために私の答えを更新しました。 –

関連する問題