【问题标题】:Agent not getting executed代理没有被执行
【发布时间】:2013-06-24 08:25:06
【问题描述】:

我有一系列函数(如示例中的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

【问题讨论】:

  • 代理或裁判是否添加了validators
  • 是的,这些函数操作的一些引用具有关联的验证器。
  • 如果 ref 的新状态没有被它的任何验证器验证,那么事务中代理上的所有 sendsend-off 都可能被丢弃。
  • 看起来可能是这样,会检查一下。无论如何,这种行为的失败沉默是非常不可取的......
  • 验证并不是我问题的根源。还有其他想法吗?

标签: concurrency clojure stm


【解决方案1】:

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

的范围来测试这一点

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2017-05-12
      • 1970-01-01
      • 2020-06-20
      • 2013-09-11
      • 1970-01-01
      • 1970-01-01
      • 2014-04-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多