Clojure Recipe for Dynamic Channels / pub-sub

时间:2018-05-10 01:57:18

标签: clojure core.async

我正在寻找一种使用core.async(或任何可行的方式)动态构建发布订阅者的方法。

问题:我需要根据邮件的:sender处理消息。每条消息都将通过相同的功能进行操作,但要点每个发件人的消息将按顺序处理,一次一个 - 基于{{1的多个主题每个密钥与一个消费者。我还需要一种方法来限制所有订阅中的活动使用者数量,以降低资源利用率。

我的想法是我会有一个:sender频道:

pub

但我希望能够确保在新发件人上线时始终有订阅者。只要代码保持小而简单,我就可以使用更好的设施。

问题:在发送邮件之前,是否存在确保特定发布的订阅者的惯用方法?如何协调每个订阅的所有使用者以使用共享线程池?

编辑:我已经找到了如何使用线程池和每个主题的单个使用者来协调工作。我认为,为了检查子是否存在,我将使用地图的参考来将主题名称存储到子。如果ref没有订阅者的条目,我会创建一个并将其添加到地图中;接下来,我将订阅者注册到出版物并发布消息。这个问题的目的是看看是否有更好的方法来启动和跟踪动态创建主题的订阅者。

1 个答案:

答案 0 :(得分:0)

我想出的解决方案是使用ref

(def registration (ref {}))

此注册由写入之前写入发布通道的线程使用:

(defn register
  [registration topic-name]
  (dosync
    (let [r (ensure registration)
          something-to-track :tracked] ;; In my case, I'm keeping track of a channel
      (when-not (get r topic-name)
        (alter registration assoc topic-name something-to-track)
        something-to-track))))

每当我们需要发布消息时,我们都可以使用此功能来注册"新订户。如果以前不存在,则返回something-to-track。在我的情况下,它是一个我将随后致电sub的频道。如果是nil,我可以忽略它。为了真正不会错过并发环境中的消息,我需要在事务中做一些事情(需要了解ensure是否可以通过跨线程提供对registration的独占访问权来保护我,但我的管道是如此我可以写pub单线程。