I have discovered that, in the case of an agent action exception, the behavior of agent await depends on timing:
- If your await happens to execute after the action is completed, it will happily throw an exception that the agent is in a failed state.
- If your await happens to execute before the action is completed, it will dangerously block. (!!!)
Shouldn't await behave the same in both cases?
Code example:
(defn await-agent-after-fail []
(let [agt (agent nil)]
(send-off agt (fn [_]
(println "Agent throws exception now")
(throw (ex-info "fail!" {}))))
(Thread/sleep 1000)
(println "Agent is awaited now...")
(println "Await timed out?" (not (await-for 10000 agt)))))
(comment
(await-agent-after-fail))
(defn await-agent-before-fail []
(let [agt (agent nil)]
(send-off agt (fn [_]
(Thread/sleep 1000)
(println "Agent throws exception now")
(throw (ex-info "fail!" {}))))
(println "Agent is awaited now...")
(println "Await timed out?" (not (await-for 10000 agt)))))
(comment
(await-agent-before-fail))