【问题标题】:Using http-kit long polling with core.async channels使用带有 core.async 通道的 http-kit 长轮询
【发布时间】:2014-08-24 07:59:49
【问题描述】:

我有一些长时间运行的进程,当进程完成时,它会返回一个带有结果的 core.async 通道。

现在我想使用带有 HTTP-kit 的长轮询返回该结果。 不幸的是,我有点困惑正确的做法是什么。

目前我有一个处理程序(连接到一个路由),它启动处理调用并在完成后发送结果:

(defn handler
  [request]
  (let [c (process request)] ;; long running process that returns a channel
    (http/with-channel request channel
      (http/send! channel {:status 200
                           :body (<!! (go (<! c)))))
      (http/on-close channel (fn [_] (async/close! c))))))

它有效,但我不确定这是否正确。

编辑因为 &lt;!! 被阻塞我现在正在 go-loop 中尝试非阻塞变体

(defn handler
  [request]
  (let [c (process request)]
    (http/with-channel request channel
      (async/go-loop [v (<! c)]
        (http/send! channel {:status 200
                             :body v}))
      (http/on-close channel (fn [_] (async/close! c))))))

【问题讨论】:

    标签: http asynchronous clojure core.async http-kit


    【解决方案1】:

    为什么不在 go 块中的通道上发送?

    (http/with-channel request channel
      (go (http/send! channel (<! c))))
    

    &lt;!! 是阻塞的 - 所以你的代码在处理程序中直接调用 &lt;!! c 并没有真正的优势:

    (defn handler [request] (let [c (process request)] ;; long running process that returns a channel {:status 200 :body (<!! c)}))


    针对问题更新进行编辑:更新后的代码有效 - 这是一个功能齐全的命名空间,对我有用:

    (ns async-resp.core
      (:require [org.httpkit.server :as http]
                [clojure.core.async :as async :refer (<! >! go chan go-loop close! timeout)]))
    
    (defn process
      [_]
      (let [ch (chan)]
        (go
          (<! (timeout 5000))
          (>! ch "TEST"))
        ch))
    
    (defn test-handler
      [request]
      (let [c (process request)]
        (http/with-channel request channel
          (go-loop [v (<! c)]
            (http/send! channel {:status 200
                                 :body v}))
          (http/on-close channel (fn [_] (close! c))))))
    
    (defn run
      []
      (http/run-server test-handler {}))
    

    不过,截至目前,我不得不手动将 tools.analyzer.jvm 依赖项添加到 project.clj - 因为我使用 core.async 按原样编译失败。

    检查您正在运行最新的 core.async 和分析器吗?

    【讨论】:

    • 好吧,我需要频道中的特定字段,因此代码看起来像 (go (http/send! {:status 200 :body (:field (gist.github.com/joelkuiper/…
    • 你的 gist 代码在最新的 core.async 中适用于我如果我还在我的 project.clj 中包含最新的 tools.analyzer.jvm。
    • 是的,它确实有效!谢谢:-)但是这样做是正确的方法吗?在性能和 core.async + http-kit 理念方面?
    猜你喜欢
    • 1970-01-01
    • 2017-06-11
    • 1970-01-01
    • 1970-01-01
    • 2015-10-19
    • 1970-01-01
    • 2015-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多