异步 clojure http-kit 客户端,回调写入数据库 sqlite3
async clojure http-kit client with callback writing to database sqlite3
在写入 sqlite 时,我被 http-kit 异步行为困住了 table。
到数据库的 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"}))))
谢谢
脚本无法从命令行运行的问题是 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
是 reader macro/shortcut 对于 (deref result-promise)
.
当您不想无限期地阻塞时,完整形式可能会更好 - 只需使用超时毫秒和超时值参数调用 deref
:
(deref result-promise 5000 "Didn't get response in 5 seconds. Giving up")
在写入 sqlite 时,我被 http-kit 异步行为困住了 table。
到数据库的 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"}))))
谢谢
脚本无法从命令行运行的问题是 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
是 reader macro/shortcut 对于 (deref result-promise)
.
当您不想无限期地阻塞时,完整形式可能会更好 - 只需使用超时毫秒和超时值参数调用 deref
:
(deref result-promise 5000 "Didn't get response in 5 seconds. Giving up")