首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Clojure http-kit get请求被多个异步调用卡住。

Clojure http-kit get请求被多个异步调用卡住。
EN

Stack Overflow用户
提问于 2017-07-28 16:24:37
回答 2查看 635关注 0票数 0

我创造了一个很小的例子,突出了这个问题:

代码语言:javascript
复制
(->> (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日志库。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-29 14:01:08

它看起来像引起的问题,因为http客户端线程池在回调函数完成之前不会释放线程。最后,它的线程用完了。

因此,我开始思考如何更快地实现回调函数,并提出了以下解决方案:

我为http客户端get创建了异步包装函数,在回调中使用clojure.core.async/chan快速将结果放入通道,然后等待其结果并执行重回调:

代码语言:javascript
复制
(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来解决这个问题。

代码语言:javascript
复制
(->> (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 ")))))))

票数 0
EN

Stack Overflow用户

发布于 2017-07-29 08:34:02

我目前的假设是,通过耗尽线程池,您会陷入僵局:

  1. 为每个外部http/get创建一个线程
  2. 如果在线程池中创建的请求少于可用线程,则至少有一个内部http/get (这将需要一个新线程) 的服务空间。
    1. 或者在耗尽线程池之前完成了第一个请求。

  1. 一旦线程池中没有更多的线程,就无法为内部http/get服务。
  2. 由于内部请求无法完成,外部将永远被卡住。

您可以检查线程池http-kit使用窥视http/default-pool的状态。在那里你可以看到这样的东西:

代码语言:javascript
复制
#object[java.util.concurrent.ThreadPoolExecutor 0x5a99e5c "java.util.concurrent.ThreadPoolExecutor@5a99e5c[Running, pool size = 8, active threads = 0, queued tasks = 0, completed tasks = 24]"]

当你没有陷入僵局的时候。或

代码语言:javascript
复制
#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个请求时,我陷入了僵局。

问候

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45378289

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档