Clojure Agents

Most of the time, Clojure does not need locks like Java and other languages. This is because of atom s, ref s, and agent s. I’ll focus on Clojure agents in this short post.

Agents are handled in  single-threaded queues. By lining up calls of a function in a queue, no locks are needed. When combined with send-off , deadlocks won’t happen.

Here’s a quick example.

A few things are going on here, so let’s look at them.

First you need to declare your variable as an agent .

Next call a function using send-off . send  also works, but can lead to blocking threads if used improperly.

send-off  takes as arguments the defined agent , in this case x  that was defined as . Follow the agent argument with the function to be applied, and finally any additional arguments to be passed to the function. Note the first argument to the function will be the agent specified as the first argument to send-off .

send-off  creates a thread for queued calls to the function so that each call waits for the previous call to complete before running. This is useful when you want only one call to the function to happen at any time. For example, if you have database I/O or network I/O to be queued for synchronization purposes.

Note that send-off (and send) return immediately, without waiting for the agent value to update. Checking the value of the agent before the queue of sent functions is empty will result in a soon-to-be stale value.

One gotcha you need to watch for, is that after finishing using send-off, you have a lingering thread pool that needs cleaning up on application shutdown. Use shutdown-agents  to clean up after all agents. Make this call when you no longer need the agents.

The output of the above code will look like the following.

If you want to watch an agent, check into the add-watch  function. If you want to wait for an agent to update, check out the await  function.

To sum up agents: Create an agent using the agent  call. Agent send-off  creates a queue that only permits one call to a function with the agent at a time. When shutting down the program, don’t forget to call shutdown-agents  to clean up agent threads that have been pooled.


Leave a Reply

Your email address will not be published. Required fields are marked *