代理没有被执行

时间:2013-06-24 08:25:06

标签: concurrency clojure stm

我有一系列功能(例如示例中的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块(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

2 个答案:

答案 0 :(得分:0)

值得了解senddosync互动的方式。 send中对dosync的所有调用只发生一次,并且只在事务提交时发生这会阻止将消息传递给代理,从而形成稍后被丢弃的事务。您可以通过缩小dosync

的范围来测试这一点

答案 1 :(得分:0)

发送池是有限的,因此只能同时执行一定数量的代理(请参阅this answer)。可能是这种情况吗?