Drain an addon's calls in flight before it is plugged OUT.
A host wraps every addon handler with tracked, so each call is admitted and
counted through an IDrainGate. drain! closes the gate for the ids about to
go (new calls are refused with ex-data {:error :hot/draining}), then waits,
bounded by :drain-ms, until the calls already admitted have finished.
drain-verdict reads the outcome; open! admits calls again.
drain-gate builds the default adapter over ONE process-wide counter map, so
the host's dispatch wrap and eject! observe the same calls.
Drain an addon's calls in flight before it is plugged OUT.
A host wraps every addon handler with `tracked`, so each call is admitted and
counted through an IDrainGate. `drain!` closes the gate for the ids about to
go (new calls are refused with ex-data {:error :hot/draining}), then waits,
bounded by :drain-ms, until the calls already admitted have finished.
`drain-verdict` reads the outcome; `open!` admits calls again.
`drain-gate` builds the default adapter over ONE process-wide counter map, so
the host's dispatch wrap and eject! observe the same calls.(atom-drain-gate)A fresh IDrainGate over its own counters.
A fresh IDrainGate over its own counters.
(busy-message report)Pure. The refusal a :busy drain answers with.
Pure. The refusal a :busy drain answers with.
How long drain! waits for calls in flight when :drain-ms is not given.
How long `drain!` waits for calls in flight when :drain-ms is not given.
How often drain! re-reads the counters.
How often `drain!` re-reads the counters.
(dispatch-handler id handler & [{:keys [inner refused gate]}])HANDLER of addon ID as a host dispatches it, so every IAddon can be drained
on unmount without code of its own: INNER (fn [id handler] -> handler), the
host's own wrap, is applied first; the result is counted through GATE
(default drain-gate); a call refused while ID drains is answered by
(REFUSED message id) instead of thrown. Any other failure still throws.
opts: {:inner fn? :refused fn? :gate IDrainGate?}. Without :refused the
refusal is thrown as tracked throws it.
HANDLER of addon ID as a host dispatches it, so every IAddon can be drained
on unmount without code of its own: INNER (fn [id handler] -> handler), the
host's own wrap, is applied first; the result is counted through GATE
(default `drain-gate`); a call refused while ID drains is answered by
(REFUSED message id) instead of thrown. Any other failure still throws.
opts: {:inner fn? :refused fn? :gate IDrainGate?}. Without :refused the
refusal is thrown as `tracked` throws it.(drain! gate ids & [{:keys [drain-ms poll-ms now sleep!]}])Close GATE for IDS, then wait until none of them has a call in flight or
:drain-ms has passed. The gate stays CLOSED either way; open! re-opens it.
opts: {:drain-ms ms :poll-ms ms :now (fn [] ms) :sleep! (fn [ms])} Returns a DrainReport: {:hot/draining [id] :hot/in-flight {id n} :hot/waited-ms ms :hot/drain-ms ms} :hot/in-flight is what was still running when the wait ended.
Close GATE for IDS, then wait until none of them has a call in flight or
:drain-ms has passed. The gate stays CLOSED either way; `open!` re-opens it.
opts: {:drain-ms ms :poll-ms ms :now (fn [] ms) :sleep! (fn [ms])}
Returns a DrainReport:
{:hot/draining [id] :hot/in-flight {id n} :hot/waited-ms ms :hot/drain-ms ms}
:hot/in-flight is what was still running when the wait ended.(drain-gate)The IDrainGate over the process-wide counters every host wrap and eject! share.
The IDrainGate over the process-wide counters every host wrap and eject! share.
(drain-verdict report force?)Pure. How a plug OUT reads a DrainReport: :drained when nothing is in flight, :forced when calls remain but FORCE? was given, otherwise :busy.
Pure. How a plug OUT reads a DrainReport: :drained when nothing is in flight, :forced when calls remain but FORCE? was given, otherwise :busy.
(draining-message id)Pure. What a call refused by a closed gate is told.
Pure. What a call refused by a closed gate is told.
(draining? ex)Pure. Is EX the refusal tracked throws for a call to a draining addon?
Pure. Is EX the refusal `tracked` throws for a call to a draining addon?
(in-flight gate ids){id n} for the IDS that still have calls in flight under GATE.
{id n} for the IDS that still have calls in flight under GATE.
(open! gate ids)Admit calls to IDS through GATE again.
Admit calls to IDS through GATE again.
(tracked id handler)(tracked gate id handler)HANDLER as a call to addon ID admitted through GATE (default drain-gate).
An admitted call is counted until it returns or throws. A call arriving while
ID drains is not run: it throws ex-info with {:error :hot/draining :addon/id ID}.
HANDLER as a call to addon ID admitted through GATE (default `drain-gate`).
An admitted call is counted until it returns or throws. A call arriving while
ID drains is not run: it throws ex-info with {:error :hot/draining :addon/id ID}.cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |