执行有关clojure异步通道的超时和缓冲区溢出的任务

时间:2016-02-23 10:30:14

标签: asynchronous clojure buffer channel core.async

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

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

我在互联网上阅读了很多资料,但概念仍然有些令人困惑。

如何使用clojure.core.async?

执行此操作

修改

好的,所以我基本上设法编写了一些可以解决问题的代码。

<div>
    <div class="innerDiv">
        Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has
        survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing
        software like Aldus PageMaker including versions of Lorem Ipsum.
    </div>
</div>

但我仍然觉得这个代码需要使用GO块或其他东西进行优化。任何人都可以指出这段代码中的缺陷并在正确的方向上进行操作吗?

请注意我将使用此代码来缓存elasticsearch查询和结果或类似的内容,并在超时或缓冲区已满时存储它们。

1 个答案:

答案 0 :(得分:2)

频道具有.buf字段这一事实是一个实现细节,您不应该使用它。

不是100%关于你的要求是什么,但在使用core.async时,你必须尝试用&#34;线程&#34; (去块)做一件事并与其他&#34;线程&#34;通过渠道。

从我从代码中收集到的内容,您似乎想要:

  1. read-line读取的go块。将写给陈
  2. 立即对新值执行操作的go块。将从陈
  3. 执行缓冲的go块。将从陈读并写入另一个
  4. 使用缓冲区执行任何操作的go块。将从陈
  5. (2)和(3)需要从(1)消耗。使用mult频道,以便他们都获得(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]))))