Asynchronous 在clojure异步通道超时和缓冲区溢出时执行任务
我有一个缓存一些值的缓冲通道(假设它是一个包含许多值的列表)。现在,一旦缓冲区已满或出现超时,我必须完全读取(清空)通道 完成后,我希望通道再次开始缓存来自同一源的值,直到源为空 我在网上读了很多资料,但是概念还是有点混乱 如何使用clojure.core.async实现这一点 编辑 好的,我基本上写了一些代码来实现这一点Asynchronous 在clojure异步通道超时和缓冲区溢出时执行任务,asynchronous,clojure,buffer,channel,core.async,Asynchronous,Clojure,Buffer,Channel,Core.async,我有一个缓存一些值的缓冲通道(假设它是一个包含许多值的列表)。现在,一旦缓冲区已满或出现超时,我必须完全读取(清空)通道 完成后,我希望通道再次开始缓存来自同一源的值,直到源为空 我在网上读了很多资料,但是概念还是有点混乱 如何使用clojure.core.async实现这一点 编辑 好的,我基本上写了一些代码来实现这一点 (require '[clojure.core.async :as a :refer [>! <! >!! <!! go chan buffer cl
(require '[clojure.core.async :as a :refer [>! <! >!! <!! go chan buffer close! thread alts! alts!! timeout offer! poll! buffer put!]])
(defn on-overflow-or-timeout [channel]
(do
(println "current used space: " (count (.buf channel)))
(if (> (count (.buf channel)) 0)
(let [loop-range (range (count (.buf channel)))]
(do
(println "retrieving values.....")
(dorun
(for [i loop-range]
(println "retrieved value: " (poll! channel))
))))
(println "No values in the channel. Please restart the process....")
)))
(defn process [channel buffer-size tout]
(let [tch (timeout tout)
check-chan (chan 2)]
(loop []
(let [value (read-string (read-line))]
(do
(println "Storing the value in actual channel: " value)
(offer! channel value)
(offer! check-chan value)
; Checking only till half its capacity
(if (>= (count (.buf channel)) (int (Math/ceil (/ buffer-size 2))))
(do
(println "overflowed.....")
(on-overflow-or-timeout channel)
(recur)
)
(let [[win-val win-chan] (alts!! [check-chan tch])]
(if (nil? win-val)
(do
(println "timed out.....")
(on-overflow-or-timeout channel)
(recur)
)
(do
(println "retrieved value from check-chan: " win-val)
(recur)
)))))))))
(需要“[clojure.core.async:as a:引用[>!(计数(.buf通道))0)
(let[循环范围(范围(计数(.buf通道)))]
(做
(println“检索值…”)
(多伦
(对于[i循环范围]
(println“检索值:”(轮询!通道))
))))
(println“通道中没有值。请重新启动进程…”
)))
(defn进程[通道缓冲区大小tout]
(让[tch(超时tout)
核对陈(陈2)]
(循环[]
(让[值(读取字符串(读取行))]
(做
(println“在实际通道中存储值:”值)
(报价!渠道价值)
(报价!检查价格)
;只检查到其容量的一半
(如果(>=(计数(.buf通道))(int(数学/ceil(/buffer size 2)))
(做
(println“溢出…”)
(在溢出或超时通道上)
(重现)
)
(让[[win val win chan](备降!![check chan])]
(如果(无?温瓦尔)
(做
(println“超时…”)
(在溢出或超时通道上)
(重现)
)
(做
(println“从check chan:win val中检索到的值)
(重现)
)))))))))
但我仍然觉得这段代码需要使用GO块或其他东西进行优化。有人能指出这段代码中的缺陷并将其调整到正确的方向吗
请注意我将使用此代码缓存elasticsearch查询和结果或类似内容,并在超时或缓冲区已满时将其存储在某个位置。频道具有
.buf
字段这一事实是一个实现细节,您不应该使用它
不是百分之百地说明您的需求是什么,但在使用core.async时,您必须尝试从“线程”(go blocks)的角度来考虑,只做一件事,并通过通道与其他“线程”通信
从我从您的代码中收集的信息来看,您似乎想要:
读取行
读取的go块将写入chan(defn buffer-or-timeout [src out buffer-size tout]
(go-loop [[timeout buffer to-send]
[(a/timeout tout) [] nil]]
(when (seq to-send)
(println "flushing" to-send)
(a/>! out to-send))
(recur (a/alt!
src ([v] (if (= buffer-size (inc (count buffer)))
[(a/timeout tout) [] (conj buffer v)]
[timeout (conj buffer v) nil]))
timeout [(a/timeout tout) [] buffer]))))
向我们展示一些代码以及您遇到的问题?@glts我很抱歉,我甚至无法开始编码,因为我对core.async感到非常困惑。我不是在要求一个完整的解决方案。只是整个过程的一个小提纲,或者甚至是某种伪代码。@glts我已经编写了一些代码。请看一下,并指出f法律。