Inadequate behavior of agent await?

99 views
Skip to first unread message

Ernesto Garcia

unread,
Jun 10, 2020, 4:48:51 AM6/10/20
to Clojure
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))

Sam Griffith

unread,
Jun 10, 2020, 11:52:29 PM6/10/20
to Clojure
You may want to ask this on ClojureVerse or on the official Q/A site at https://ask.clojure.org/index.php/

Sean Corfield

unread,
Jun 11, 2020, 12:20:19 AM6/11/20
to Clojure Mailing List
If you provide an error handler on the agent -- or just specify the error mode as :continue -- it does not hang. That makes me think that what you're seeing is "expected behavior" although it does seem a bit strange...?

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/9cf9a5c3-1dcb-4d4a-b180-a2cd6568853do%40googlegroups.com.


--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- https://corfield.org/
World Singles Networks, LLC. -- https://worldsinglesnetworks.com/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)

Ernesto Garcia

unread,
Jun 11, 2020, 9:32:50 AM6/11/20
to Clojure
Hey, thanks for the suggestions. ClojureVerse seems to be the most active forum?

Ernesto Garcia

unread,
Jun 11, 2020, 10:18:39 AM6/11/20
to Clojure
On Thursday, June 11, 2020 at 6:20:19 AM UTC+2, Sean Corfield wrote:
If you provide an error handler on the agent -- or just specify the error mode as :continue -- it does not hang.

Thanks for pointing out those solutions.
 
That makes me think that what you're seeing is "expected behavior" although it does seem a bit strange...?

Yes, `await` doc says: "Will block on failed agents". We should infer that we should only use `await` when we ensure that the agent continues on exceptions. Looking into the implementation of `await`, it creates a latch, sends a `latch.countDown()` action to the agent, and awaits that latch. It makes sense that it blocks forever if the agent stops processing actions.

However, there's a thing I don't understand. `await` doc says: "Blocks the current thread (indefinitely!) until all actions dispatched thus far, from this thread or agent, to the agent(s) have occurred." But, considering its implementation, we seem to be waiting for all actions to occur, not only the actions dispatched by this thread. Also, we are not allowed to call `await` from inside an agent action; why does it say "from this thread or agent" then?

Am I misinterpreting something?

Thanks,
Ernesto

Matching Socks

unread,
Jun 13, 2020, 7:44:35 AM6/13/20
to Clojure
await takes many steps and is not synchronized, so it would be messy to guarantee how it relates to other threads.
Reply all
Reply to author
Forward
0 new messages