【发布时间】:2013-06-24 08:25:06
【问题描述】:
我有一系列函数(如示例中的some-operation),我将其send 或send-off 给代理:
(defn some-operation [agent-state]
(dosync
(let [updated (foo agent-state)] ;; derive new state from old one
(alter bar whatev updated) ;; reflect the new state in the world
(send *agent* some-operation) ;; "recur"
updated) ;; value for recur
))
(send (agent {}) some-operation)
在我开发应用程序时,这种方法对我很有效。但是在代码库中进行一些更改后,代理会在一段时间后停止运行(“一段时间”是几秒钟 - 几千次“递归”调用)。
他们的状态在域中是有效的,代理本身没有FAILED,我确信他们没有在他们的dosync块上活锁(one can measure contention)。
我怀疑 JVM/OS 出于某种或其他原因正在阻止底层执行程序线程运行。但我不知道如何检查这个假设是否正确。
一般来说,发送代理可能无法执行其挂起的“发送”的可能原因有哪些?我可以检查/测量什么?
更新 - 给定以下调试修改...
(defn some-operation [agent-state]
(let [f (future
(dosync
...) ;; the whole operation, as per the previous example
)]
(Thread/sleep 1000) ;; give the operation some time
(if (realized? f)
@f
;; not realized: we deem the operation as blocking indefinetely
(do
(println :failed)
(send *agent* some-operation)
agent-state))))
...代理仍然卡住,甚至不打印:failed。
【问题讨论】:
-
代理或裁判是否添加了validators?
-
是的,这些函数操作的一些引用具有关联的验证器。
-
如果 ref 的新状态没有被它的任何验证器验证,那么事务中代理上的所有
send或send-off都可能被丢弃。 -
看起来可能是这样,会检查一下。无论如何,这种行为的失败沉默是非常不可取的......
-
验证并不是我问题的根源。还有其他想法吗?
标签: concurrency clojure stm