Clojure的HTTP-KIT陷在多个异步请求调用
我创建了突出问题的小例子:Clojure的HTTP-KIT陷在多个异步请求调用
(->> (range 0 4)
(mapv (fn [i]
(http/get "http://http-kit.org/"
(fn [res]
(info "first callback")
(let [res2 @(http/get "http://http-kit.org/")]
(info "second callback ")))))))
它贴在打印4S第一回调味精的。
如果我改变了0..3它会工作范围,同步版本也适用。
更新:
的(info)
是taoensso.timbre
日志库
它看起来像问题造成的,因为直到回调函数完成HTTP-KIT客户线程池不解除线程。因此,它结束了线程的用完。
于是我开始思考如何使回调函数更快,这种解决方案提出了:
我创建异步包装函数用于HTTP-KIT客户获得其在回调使用clojure.core.async/chan
赶紧把结果在通道然后等待它的结果和执行重回调:
(defn async-http-get
[url opts callback]
(let [channel (chan)]
(http/get url opts #(go (>! channel %)))
(go (callback (<! channel)))
nil))
所以现在使用的async-http-get
代替http/get
解决这个问题对我来说。
(->> (range 0 4)
(mapv (fn [i]
(async-http-get "http://http-kit.org/"
(fn [res]
(info "first callback")
(let [res2 @(http/get "http://http-kit.org/")]
(info "second callback ")))))))
我现在的假设是,你进入一个僵局被耗尽你的线程池:
- 您创建一个线程每个外部http /获得
- 如果您创建的线程池中的可用线程数少于请求线程数,则有空间起动转矩至少一个内部
http/get
(这将需要一个新的线程)- 或者,如果你耗尽线程池
- 一旦有在线程池中没有更多的线程之前,你的第一个请求完成,内
http/get
不能 提供服务 - 由于内请求无法完成,是,外表面永远
卡您可以检查线程池的状态HTTP的套件使用偷看http/default-pool
。在那里你可以看到类似的东西:
#object[java.util.concurrent.ThreadPoolExecutor 0x5a99e5c "[email protected][Running, pool size = 8, active threads = 0, queued tasks = 0, completed tasks = 24]"]
当你没有进入僵局。或
#object[java.util.concurrent.ThreadPoolExecutor 0x5a99e5c "[email protected][Running, pool size = 8, active threads = 8, queued tasks = 8, completed tasks = 28]"]
你这么做的时候。
我已经在我的机器上测试过了(显示8为(.availableProcessors (Runtime/getRuntime))
),我得到了上面的结果。当我运行8个以上的请求时,我陷入了僵局。
问候
是的,我也在想这是一个问题,你能重现这个问题吗? – Grievoushead
是的,在我的使用'(.availableProcessors(Runtime/getRuntime))'的方框中,如果我运行了8个以上的请求,它们就会卡住。 –
我看不出有什么问题,运行的时候。您将获得4个可减值的向量,打印4个“第一个回调”,并打印4个“第二个回叫”。作为一个完整性检查,请记住'(范围0 4)'是4个元素,而不是5个。 – Josh
@Josh你可以尝试将范围更改为10个元素吗? – Grievoushead
@Josh我认为它可能会在差异机器上取决于CPU核心。对我而言,我刚刚重新启动了我的Mac,并得到了4个可供应的响应,4个“第一个回调”被打印出来然后卡住了。 – Grievoushead