What is the difference between Clojure's "send" and "send-off" functions with respect to dispatching an action to an agent?

3.3k views Asked by At

The Clojure API describes these two functions as:

(send a f & args) - Dispatch an action to an agent. Returns the agent immediately. Subsequently, in a thread from a thread pool, the state of the agent will be set to the value of: (apply action-fn state-of-agent args)

and

(send-off a f & args) - Dispatch a potentially blocking action to an agent. Returns the agent immediately. Subsequently, in a separate thread, the state of the agent will be set to the value of: (apply action-fn state-of-agent args)

The only obvious difference is send-off should be used when an action may block. Can somebody explain this difference in functionality in greater detail?

1

There are 1 answers

3
Arthur Ulfeldt On BEST ANSWER

all the actions that get sent to any agent using send are run in a thread pool with a couple of more threads than the physical number of processors. this causes them to run closer to the cpu's full capacity. if you make 1000 calls using send you don't really incur much switching overhead, the calls that can't be processed immediately just wait until a processor becomes available. if they block then the thread pool can run dry.

when you use send-off, a new thread is created for each call. if you send-off 1000 functions, the ones that can't be processed immediately still wait for the next available processor, but they may incur the extra overhead of starting a thread if the send-off threadpool happens to be running low. it's ok if the threads block because each task (potentially) gets a dedicated thread.