An agent is created with
agent
and the associated data. You can use deref
or @
to access the data associated with an agent (same syntax as I mentioned previously for atoms).
user> (agent '(1 2 3 4 5 6))
#
user> @(agent '(1 2 3 4 5 6))
(1 2 3 4 5 6)
Agents are reactive - they'll only do something if you tell them so. All communication with agents is through functions. There are two commands for sending functions to agents,
send
(used for non-blocking calls) and send-off
(used for potentially blocking calls). Both send
and send-off
return immediately, the difference being that send-off
guarantees the message will be processed in a different thread.
user> (let [a (agent 4)]
(send a + 1) ; schedules a call of (apply + agent_state 1)
(await a)
(prn @a))
5
nil
Without the invocation of
await
, this may return 4 not 5. await
blocks the current thread indefinitely until all actions have been completed (which makes it quite dangerous!).What if the function you are sending has errors? Let's look at a divide by zero:
user> (let [a (agent 4)]
(send a / 0)
(await a)
(prn @a))
; Evaluation aborted.
java.lang.Exception: Agent has errors (NO_SOURCE_FILE:0)
[Thrown class clojure.lang.Compiler$CompilerException]
Errors in agents can be inspected with
agent-errors
which returns a sequence of exceptions. Once an agent is in an error state it can not process any more messages until the errors have been cleared with clear-agent-errors
.
user> (let [a (agent 4)]
(send a / 0)
(await a)
(prn (agent-errors a))
(clear-agent-errors a)
(prn @a))
(#)
4
nil
So agents seem incredibly simple - why are they so powerful?
- Integration with STM, which leads too...
- Always observable - no matter what calculation is going on, you can always get the current (valid) value with
deref
. - No message-loops - agents are purely reactive which (to me) seems a simpler programming model to understand
- Open - agents are mutated by functions and therefore this can be extended by anyone (in contrast with having to add a new type of message for the loop to switch on)
No comments:
Post a Comment