Использование длинного опроса http-kit с каналами core.async
У меня есть какой-то долго работающий процесс, который возвращает канал core.async с результатом на нем, когда процесс завершится.
Теперь я хотел бы вернуть этот результат с помощью длинного опроса с HTTP-комплектом. К сожалению, я немного запутался, как правильно поступить.
В настоящее время у меня есть обработчик (подключен к маршруту), который инициирует вызов обработки и отправляет результат по завершении:
(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))))))
Это работает, но я не уверен, что это правильный путь.
РЕДАКТИРОВАТЬ с <!!
блокирует, я сейчас пытаюсь неблокирующий вариант в 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))))))
1 ответ
Почему бы не отправить на канал в блоке go?
(http/with-channel request channel
(go (http/send! channel (<! c))))
<!!
блокирует - так что нет никакого реального преимущества в вашем коде от прямого вызова <!! 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 и анализатора?