Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asynchronous 在clojure异步通道超时和缓冲区溢出时执行任务_Asynchronous_Clojure_Buffer_Channel_Core.async - Fatal编程技术网

Asynchronous 在clojure异步通道超时和缓冲区溢出时执行任务

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

我有一个缓存一些值的缓冲通道(假设它是一个包含许多值的列表)。现在,一旦缓冲区已满或出现超时,我必须完全读取(清空)通道

完成后,我希望通道再次开始缓存来自同一源的值,直到源为空

我在网上读了很多资料,但是概念还是有点混乱

如何使用clojure.core.async实现这一点

编辑

好的,我基本上写了一些代码来实现这一点

(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
  • 对新值立即起作用的go块。将从
  • 执行缓冲的go块。将从一个chan读取数据并写入另一个chan
  • 对缓冲区执行任何操作的go块。将从chan中读取
  • (2) 和(3)需要从(1)消费。使用一个通道,这样他们都可以得到(1)所写内容的副本。 (4) 可以直接从(3)中读取

    (3)的可能实现如下所示:

    (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法律。