Clojure:需要建筑建议

时间:2012-07-13 01:43:52

标签: clojure publish-subscribe

我正在写一个小的clojure pub / sub接口。这是非常准确的,只有两种方法可以实际使用:do-pub和sub-listen。 sub-listen采用字符串(子名称),do-pub采用两个字符串(子名称和值)。

我在clojure方面仍然相当新,并且在提出可行的方法时遇到一些麻烦。我的第一个想法(实际上是我的第一个实现)使用了一个包含哈希的代理:

{ subname (promise1 promise2 etc) }

当一个线程想要将它的一个promise对象联合到与它想要的子关联的列表时,然后立即尝试取消引用该promise(因此阻塞)。

当一个pub发生时,它会遍历sub的列表中的每个项目,并将值传递给该项目(promise)。然后它从地图中取消该子名称并将其返回给代理。

通过这种方式,我得到了一个简单的pub子实现工作。然而,问题出现在有人潜水,在一段时间内没有收到酒吧,然后因超时而被杀死。在这种情况下,代理中将存在一个不需要的无价值的承诺,而且如果该子类永远不会被发布,那么这将是内存泄漏的来源。

有没有人对如何解决这个问题有任何想法?或者,如果有更好的方法来做我想要做的整体(我试图避免使用任何外部预先煮熟的pubsub库,这是一个宠物项目而不是一个工作)?

2 个答案:

答案 0 :(得分:3)

您可以这样做:

  • 创建atom
  • publish函数将通过传入的值更新原子值到函数
  • 订阅者可以在原子上使用add-watch来通知原子值何时发生变化,即由于调用publish函数
  • 使用remove-watch删除订阅。

这样你就有了一个非常基本的pub-sub系统。

答案 1 :(得分:3)

我已将Ankur的答案标记为解决方案,但我想稍微扩展一下。我最终做的是拥有一个中心原子,所有客户端线程都在add-watch上。完成pub后,atom的值将更改为包含sub名称和pub'd值的向量。

客户端传递给add-watch的函数是部分函数,​​看起来像

(partial (fn [prom sub key ref _old new] ...) sub prom)

其中,prom是先前生成的承诺。然后客户端在等待该承诺时阻塞。部分函数检查new中的子信息是否与sub相同,如果是,则删除监视并使用new的值传递保证。