【发布时间】:2011-08-05 20:38:56
【问题描述】:
我正在使用 Java 的 new I/O package 为 Clojure 编写一个简单的网络框架。它管理着一个“选择器代理”池,每个代理都拥有一个Selector。
我为选择器代理定义了一个dispatch 操作。此操作会阻止对 selector.select() 的调用。当它返回时,选择器代理迭代选定的键并执行 I/O。当 I/O 完成时,选择器代理使用send-off 向自己发送dispatch 操作,有效地循环调用selector.select()。
当我想添加新频道或更改频道的interest ops 时,我会向选择器代理发送适当的操作,然后取消阻止选择器(它在select() 上被阻止,记得吗?)。这确保了选择器代理中的(send-off selector-agent dispatch) 在(send selector-agent add-channel channel) 之后执行。
我认为这将是防弹的,因为对send-off 的调用是在选择器唤醒之前执行的,因此,在选择器代理向自身发送dispatch 操作之前。但是,这会产生不一致的行为。有时,dispatch 操作首先发生,有时则不会。
我的理解是,不能保证代理在来自多个线程时按照它们发送的确切顺序执行操作(即,就排队操作而言,send 和 send-off 不是同步的)。
这对吗?
【问题讨论】:
-
如果你想在 Clojure 中建立 NIO 网络,我通常会推荐优秀的 Aleph 库 (github.com/ztellman/aleph),而不是自己编写......有什么理由不能使用它吗?
-
@mikera:有限状态机 (FSM) 是异步服务器的一个非常好的设计。我喜欢使用 Clojure 代理开发有限状态机是多么容易,并试图弄清楚我是否可以使用 Clojure 代理来实现网络协议(特别是 FTP,它需要为单个客户端操作两个连接)。这不是用于生产开发,而是对 Clojure 代理的实验 :-)
标签: clojure