Agents are for asynchronous, independent state changes. Each agent has a value plus a queue of actions. Actions are applied serially per agent, but run asynchronously on thread pools.
Use agents when:
- updates should happen in the background (logging, metrics aggregation, caches)
- state updates are independent (no multi-agent transaction/invariant)
Create and Read
1(def stats (agent {:requests 0 :errors 0}))
2
3@stats ; => {:requests 0, :errors 0}
Update with send
send queues an action (a function) to apply to the agent’s current state:
1(send stats update :requests inc)
2(send stats update :errors inc)
Actions are functions of the current state → new state.
send vs send-off
send is intended for CPU-bound actions.
send-off is intended for potentially blocking actions (I/O).
Waiting and Errors
1(await stats) ; wait for queued actions to finish
2(agent-error stats) ; => exception or nil
If an action throws, the agent enters a failed state and stops processing future actions until you handle it (for example with restart-agent).
Knowledge Check: Agents
### What does `send` do?
- [x] Queues an action function to run asynchronously and update the agent’s state.
- [ ] Mutates the agent immediately on the current thread.
- [ ] Starts a Java thread per update.
- [ ] Updates multiple agents atomically.
> **Explanation:** `send` enqueues a function to be applied to the agent’s state. Actions are processed serially for that agent.
### When should you prefer `send-off` over `send`?
- [x] When the action may block (I/O, long waits), so you don’t starve the CPU-bound pool.
- [ ] When you need atomic updates across two values.
- [ ] When you need a synchronous update.
- [ ] When you want retries like `swap!`.
> **Explanation:** `send-off` uses a separate pool intended for blocking work. It’s a safety/performance choice, not a semantic one.
### What happens if an agent action throws an exception?
- [x] The agent enters an error state and stops processing queued actions until handled.
- [ ] The exception is ignored and actions continue.
- [ ] The agent automatically retries the action until it succeeds.
- [ ] The JVM exits.
> **Explanation:** Agent failures are explicit. Check with `agent-error` and recover with `restart-agent` when appropriate.