4

我有一系列功能(如some-operation示例中的),我sendsend-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块上活锁(可以衡量争用)。

我的怀疑是 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

4

2 回答 2

0

值得了解的方式senddosync交互。所有对in 的调用仅发生一次,并且仅在事务提交时才发生。senddosync这可以防止将消息传递给代理,形成以后被丢弃的事务。您可以通过缩小范围来测试dosync

于 2013-06-24T21:44:44.453 回答
0

发送池受到限制,因此只能同时执行一定数量的代理(请参阅此答案)。可能是这样吗?

于 2013-07-23T10:42:26.237 回答