Reputation: 4740
I have some long running process that returns a core.async channel with the result on it when the process has finished.
Now I'd like to return that result using long-polling with HTTP-kit. Unfortunately I'm a bit confused what the right way of doing so is.
Currently I have a handler (hooked up to a route) that initiates the processing call and sends the result when done:
(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))))))
It works, but I'm unsure if this is the right way.
EDIT since <!!
is blocking I'm now trying a non-blocking variant in a 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))))))
Upvotes: 2
Views: 1010
Reputation: 1103
Why not send on the channel in the go block?
(http/with-channel request channel
(go (http/send! channel (<! c))))
<!!
is blocking - so there is no real advantage in your code from just directly calling <!! c
in the handler:
(defn handler
[request]
(let [c (process request)] ;; long running process that returns a channel
{:status 200
:body (<!! c)}))
Edit in response to question update: The updated code works - this is a fully functioning namespace which works for me:
(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 {}))
As of the current moment in time though, I had to manually add the tools.analyzer.jvm dependency to project.clj - as I get compilation failures using core.async as-is.
Check you're running the latest core.async and analyzer?
Upvotes: 1