When to stop calling a service that keeps failing.
Retries bound the damage of one call; this bounds the damage of many. A service that is down still receives every request until each one times out, and every caller pays that timeout. Declining to call is the only thing that stops both.
FC/IS: pure. The state lives elsewhere — see …shell.rpc.breaker, which
keeps it in the cache so replicas share one breaker rather than each
discovering the outage separately.
When to stop calling a service that keeps failing. Retries bound the damage of one call; this bounds the damage of many. A service that is down still receives every request until each one times out, and every caller pays that timeout. Declining to call is the only thing that stops both. FC/IS: pure. The state lives elsewhere — see `…shell.rpc.breaker`, which keeps it in the cache so replicas share one breaker rather than each discovering the outage separately.
(ceil-seconds ms)ms as whole seconds, rounded up, never less than one.
Cache TTLs are in seconds and breaker windows are in milliseconds, so the
conversion has to round the right way: flooring an :open-ms of 1500 to one
second makes the stored state expire before the window it describes has
elapsed, and the breaker forgets an outage it is still meant to be
protecting against.
`ms` as whole seconds, rounded up, never less than one. Cache TTLs are in seconds and breaker windows are in milliseconds, so the conversion has to round the right way: flooring an `:open-ms` of 1500 to one second makes the stored state expire before the window it describes has elapsed, and the breaker forgets an outage it is still meant to be protecting against.
(config-problem config)Why config is unusable, or nil.
Why `config` is unusable, or nil.
(counts-as-failure? config error-type)Whether error-type is evidence the service is unreachable.
:rpc/timeout counts here although it is not retried. Retrying a timeout
risks running a non-idempotent call twice; declining to make a new call
risks nothing. The two decisions read alike and are not.
Whether `error-type` is evidence the service is unreachable. `:rpc/timeout` counts here although it is not retried. Retrying a timeout risks running a non-idempotent call twice; declining to make a new call risks nothing. The two decisions read alike and are not.
(error operation base-url retry-after-ms)The error a caller gets when the breaker declined to make the call.
The error a caller gets when the breaker declined to make the call.
(on-failure {:keys [failures]} config now-ms)The breaker after a failed call.
Trips at the threshold and not before, so one blip does not take a service out of service.
The breaker after a failed call. Trips at the threshold and not before, so one blip does not take a service out of service.
(on-success _breaker)The breaker after a call that reached the service.
Reset outright rather than decremented: the count is of consecutive failures, and one success says the run has ended.
The breaker after a call that reached the service. Reset outright rather than decremented: the count is of *consecutive* failures, and one success says the run has ended.
(retry-after-ms {:keys [opened-at-ms]} config now-ms)How long until the breaker will next allow a probe.
How long until the breaker will next allow a probe.
(state {:keys [opened-at-ms]} config now-ms):closed, :open or :half-open for breaker at now-ms.
:half-open is not stored — it is what :open becomes once the window has
elapsed. Deriving it means nothing has to run on a timer to move the
breaker on.
`:closed`, `:open` or `:half-open` for `breaker` at `now-ms`. `:half-open` is not stored — it is what `:open` becomes once the window has elapsed. Deriving it means nothing has to run on a timer to move the breaker on.
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 |