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:需要架构建议的主要内容,如果未能解决你的问题,请参考以下文章

Clojure 内容类型?

庄晓丹:Java程序员眼中的Clojure

Clojure学习笔记——介绍安装和语法

为什么需要用 Clojure 来开发你的下一个微服务

在 Clojure 中需要命名空间时出现 FileNotFoundException

从clojure中的普通lisp替换(null x)函数的惯用方法