I have a number of functions (for example, some-operation in the example) that I send or send-off for agents:
(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)
This approach worked for me when I was developing my application. But after some changes in the code base, agents simply stop working after some time ("some time" - a few seconds - "recursive" calls).
Their state is valid in the domain, the agents themselves do not have FAILED , and I am sure that they do not expect their dosync blocks ( you can measure the statement ).
My suspicious fact is that the JVM / OS prevents the threads of the base executor from starting, for one reason or another. But I do not know how to verify the correctness of this assumption.
In general, what are the possible reasons why a dispatch agent might not complete pending โdispatchesโ? What can I check / measure?
Update - taking into account the following modification for debugging ...
(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))))
... the agent is still stuck and does not even print :failed .
source share