2

プロセスが終了したときに結果を含む 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))))))

動作しますが、これが正しい方法かどうかはわかりません。

編集はブロックされているため<!!、現在、ゴーループで非ブロックバリアントを試しています

(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))))))
4

1 に答える 1

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 とアナライザーを実行していることを確認しますか?

于 2014-07-03T09:26:38.813 に答える