使用 clojure core async with ring 的任何简单解决方案(vertx/ring 适配器)

any simple solution for use clojure core async with ring (vertx/ring adapter)

这可能是在环中处理异步通道的最佳方式,基本上我需要在我的处理程序中获取通道的响应,然后提供响应

(GET "/slow/:a" [a] (slow-request2 a))

;;this function do a slow operation simulating a slow request
(defn slow-response [a]
  (let [ch (!/chan 1)]
    (!/go (Thread/sleep 10000)
          (print "running slow")
          (!/>! ch (+ 1 a)))
    ch))

;;based in the recommendation from http://www.reddit.com/r/Clojure/comments/2ka3na/how_do_you_organize_your_coreasync_code/cljbz2q


(defn slow-request [a]
  (!/go-loop
    [v (!/<! (slow-response a))]
    (when v (do
              (print "response v")
              {:status 200 :body v}))))

(defn slow-request2 [a]
  (!/go
    (while true
      {:status 200 :body (!/<! (slow-response a))})))

不幸的是我得到了这个错误

java.lang.IllegalArgumentException 在 /slow/10

未实现方法::render of protocol: #'compojure.response/Renderable found for class: clojure.core.async.impl.channels.ManyToManyChannel

似乎处理程序正在尝试响应整个 go 块而不是我的请求主体,除了使用阻塞响应外,我找不到没有副作用的处理响应的解决方案

在这种情况下哪种方法最好?

注意:我正在使用 vertx/ring 适配器,所以 http/kit 现在不是一个选项,我需要找到一种方法来处理响铃响应中的通道

您需要对 core.async 通道执行阻塞操作,以强制其为一个值。否则处理程序将 return 通道本身而不是通道上的值。

如果您需要在请求中支持异步,请考虑使用 Pedestal

此外,在 go 块内时,更喜欢 timeout chan 而不是 Thread/sleep。