【问题标题】:Clojure: architecture advice neededClojure:需要架构建议
【发布时间】: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 库,这是一个宠物项目而不是一个工作项目)?

【问题讨论】:

    标签: clojure publish-subscribe


    【解决方案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 的值传递承诺。

      【讨论】:

        猜你喜欢
        • 2014-11-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-02
        • 1970-01-01
        • 2011-06-01
        • 1970-01-01
        • 2011-04-21
        • 1970-01-01
        相关资源
        最近更新 更多