ClojureDocs

Nav

Namespaces

send-off

clojure.core

Available since 1.0 (source)
  • (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)
2 Examples
user=> (def my-agent (agent ""))
#'user/my-agent
user=> @my-agent
""

;; Note the following happens asynchronously in a thread
;; pool
user=> (send-off my-agent #(slurp %2) "file.txt")
#<Agent@13c6641: "">

;; while the slurp is in-progress, @my-agent will return "".

;; Once the request has completed, the value will
;; be updated when we look at it.
user=> @my-agent
"file contents"
;; send should be used for actions that are CPU limited,
;; while send-off is appropriate for actions that may block on IO.

;; send is like async/go, send-off is like async/thread
;; so send use limited pool by CPU for agents to not overload CPU,
;; while send-off use independent threads without limitations.
See Also

Dispatch an action to an agent. Returns the agent immediately. Subsequently, in a thread from a th...

Added by gstamp

Creates and returns an agent with an initial value of state and zero or more options (in any order...

Added by gstamp

Initiates a shutdown of the thread pools that back the agent system. Running actions will complete...

Added by gstamp

Dispatch an action to an agent. Returns the agent immediately. Subsequently, in a thread supplied ...

Added by Crowbrammer
2 Notes
    By , created 11.0 years ago

    The example uses "send", this is supposed to be an example for "send-off".

    By , created 10.3 years ago, updated 10.3 years ago

    "send" and "send-off" are identical in syntax and semantics. The only difference is the thread pool used to dispatch the agent. "send" uses a fixed-sized thread pool initialized at startup to contain a few more threads than the number of cores on the host computer. Since "send"s thread pool is fixed size, using it to dispatch blocking code can result in all the pool's threads being blocked, and other "send"s queued waiting for a thread to finish its work. This can produce artificially low performance, and in rare conditions, can deadlock (if a queued thread is needed to unblock the blocked pool threads).

    "send-off" uses a separate thread pool which can grow as-needed. I.e. a "send-off" request will never be queued waiting for a thread; if the existing pool is empty, a new thread is created. However, if many long-running CPU-bound (not blocking) requests are being submitted, "send-off" can be counter-productive; having more CPU-bound threads than cores results in unnecessary scheduling overhead as the threads are timeshared across the cores. "send"s limited thread pool produces higher throughput for CPU-bound requests.