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

时间:2015-03-25 18:22:54

标签: clojure ring core.async

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

(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 at / slow / 10

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

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

这可能是这种情况下最好的方法吗?

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

1 个答案:

答案 0 :(得分:1)

您需要对core.async通道进行阻止,以强制它为某个值。否则,处理程序将返回通道本身而不是通道上的值。

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

此外,在内部去块时更喜欢超时chan到线程/睡眠。