Clojure:需要架构建议
Posted
技术标签:
【中文标题】Clojure:需要架构建议【英文标题】:Clojure: architecture advice needed 【发布时间】:2012-07-13 01:43:51 【问题描述】:我正在编写一个小的 clojure pub/sub 接口。它非常简单,只有两种方法会实际使用:do-pub 和 sub-listen。 sub-listen 接受一个字符串(一个子名称),do-pub 接受两个字符串(一个子名称和一个值)。
我还是个 clojure 新手,想出一个可行的方法来做这件事时遇到了一些麻烦。我的第一个想法(实际上也是我的第一个实现)使用了一个包含哈希的单个代理:
subname (promise1 promise2 etc)
当一个线程想要将它 conj 的一个 promise 对象 sub 到与它想要的 sub 关联的列表中时,然后立即尝试取消引用该 promise(因此阻塞)。
当 pub 发生时,它会遍历列表中的每个项目,并将值传递给该项目(承诺)。然后它从映射中解散该子名称并将其返回给代理。
通过这种方式,我得到了一个简单的 pub sub 实现工作。但是,当有人订阅后,问题就出现了,在一定时间内没有收到 pub,然后由于超时而被杀死。在这种情况下,代理中将有一个不需要的毫无价值的承诺,而且如果该子永远不会被发布,这将成为内存泄漏的根源。
有人对如何解决这个问题有任何想法吗?或者,如果有更好的方法来做我想要做的事情(我试图避免使用任何外部预先准备好的 pubsub 库,这是一个宠物项目而不是一个工作项目)?
【问题讨论】:
【参考方案1】:你可以这样做:
创建一个atom
publish
函数将通过传入函数的值更新原子值
订阅者可以在 atom 上使用 add-watch
,以便在 atom 值更改时(即由于调用 publish
函数)得到通知
使用remove-watch
删除订阅。
这样您将拥有一个非常基本的发布-订阅系统。
【讨论】:
【参考方案2】:我已将 Ankur 的答案标记为解决方案,但我想对其进行一些扩展。我最终做的是拥有一个所有客户端线程都执行add-watch
的中心原子。发布完成后,原子的值将更改为包含子名称和要发布的值的向量。
客户端传递给add-watch
的函数是一个部分函数,看起来像
(partial (fn [prom sub key ref _old new] ...) sub prom)
prom 是先前生成的承诺。然后客户端在等待该承诺时阻塞。部分函数检查 new
中的 sub 是否与 sub
相同,如果是,则删除手表并使用来自 new
的值传递承诺。
【讨论】:
以上是关于Clojure:需要架构建议的主要内容,如果未能解决你的问题,请参考以下文章