Concurrency 代理没有被执行

Concurrency 代理没有被执行,concurrency,clojure,stm,Concurrency,Clojure,Stm,我有一系列功能(如示例中的某些操作),我发送或发送给代理: (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) ;

我有一系列功能(如示例中的
某些操作
),我
发送
发送给代理:

(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)
在我开发应用程序时,这种方法对我很有效。但在代码库中进行一些更改后,代理只需在一段时间后停止运行(“一段时间”是几秒钟,即数千个“递归”调用)

他们的状态在域中是有效的,代理本身没有失败,我确信他们没有在
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))))

…代理仍然被卡住,甚至没有打印
:失败
值得注意的是
发送
dosync
交互的方式。在
dosync
中对
send
的所有调用都只发生一次,并且只有在事务提交后,才能防止将消息传递给代理,从而形成一个事务,该事务随后被丢弃。您可以通过缩小
dosync

发送池的范围来测试这一点,因为发送池受到限制,因此只能同时执行一定数量的代理(请参阅)。可能是这种情况吗?

代理或ref是否添加了任何内容?是的,这些函数操作的某些ref具有关联的验证器。如果ref的新状态未经其任何验证器验证,然后,事务中代理上的所有
send
send off
都可能被丢弃。似乎情况就是这样,我们将检查它。无论如何,这种行为的失败沉默是非常不可取的……验证并不是我问题的根源。还有其他想法吗?