我创造了一个很小的例子,突出了这个问题:
(->> (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日志库。
发布于 2017-07-29 14:01:08
它看起来像引起的问题,因为http客户端线程池在回调函数完成之前不会释放线程。最后,它的线程用完了。
因此,我开始思考如何更快地实现回调函数,并提出了以下解决方案:
我为http客户端get创建了异步包装函数,在回调中使用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 ")))))))

发布于 2017-07-29 08:34:02
我目前的假设是,通过耗尽线程池,您会陷入僵局:
http/get (这将需要一个新线程) 的服务空间。
http/get服务。您可以检查线程池http-kit使用窥视http/default-pool的状态。在那里你可以看到这样的东西:
#object[java.util.concurrent.ThreadPoolExecutor 0x5a99e5c "java.util.concurrent.ThreadPoolExecutor@5a99e5c[Running, pool size = 8, active threads = 0, queued tasks = 0, completed tasks = 24]"]当你没有陷入僵局的时候。或
#object[java.util.concurrent.ThreadPoolExecutor 0x5a99e5c "java.util.concurrent.ThreadPoolExecutor@5a99e5c[Running, pool size = 8, active threads = 8, queued tasks = 8, completed tasks = 28]"]当你做的时候。
我已经在我的机器上测试过这个(显示8为(.availableProcessors (Runtime/getRuntime))),我得到了上面的结果。当我运行超过8个请求时,我陷入了僵局。
问候
https://stackoverflow.com/questions/45378289
复制相似问题