ecluse:ecluse-core
Safe HaskellNone
LanguageGHC2021

Ecluse.Core.Supervision

Description

The one supervision combinator every background loop runs under, so no loop carries a private copy of the catch-log-backoff machinery.

Typed fault channels stay in the steps: a step receiving an Either fault a from a handle makes its own domain decision and sets its own pacing. What reaches this combinator's catch is residue, an exception escaping some dependency's typed contract, plus whatever a step's policy classifies Permanent.

Synopsis

The combinator

superviseLoop :: (MonadUnliftIO m, KatipContext m) => SupervisionPolicy -> m () -> m Void Source #

Run the step forever under the policy: a completed step resets the backoff and reruns at once, since the step owns its own pacing. tryAny leaves asynchronous exceptions alone, so cancellation tears the loop down.

data SupervisionPolicy Source #

One loop's supervision policy. A loop classifies a fault that no retry can fix, such as an unconfigured handle reached at runtime, as Permanent, and everything else as Transient.

Constructors

SupervisionPolicy 

Fields

transientPolicy :: Text -> BackoffSchedule -> SupervisionPolicy Source #

The policy for a loop with no wiring fault to fail up on: every synchronous escape is residue, logged and retried at schedule's pace.

data FaultDisposition Source #

What the supervisor does with a synchronous fault the step let escape. An asynchronous exception is never classified, so cancellation propagates and the shutdown race always wins.

Constructors

Transient

Log at WarningS, back off (bounded exponential), rerun the step.

Permanent

Rethrow: fail up to the process supervisor, taking the process down.

Bounded exponential backoff

data BackoffSchedule Source #

A bounded exponential backoff, doubling from the base towards the cap as consecutive failures mount, so a persistently-failing dependency retries at most once per cap interval.

Constructors

BackoffSchedule 

Fields

backoffMicros :: BackoffSchedule -> Int -> Int Source #

The delay before the next retry, given how many failures ran consecutively: base * 2^failures, saturated at the cap.

backgroundLoopBackoff :: BackoffSchedule Source #

The pace a background loop retries a transient fault at: one second after the first failure, doubling to a thirty-second ceiling.

Bounded retry pacing

delayListPolicy :: forall (m :: Type -> Type). Monad m => [Int] -> RetryPolicyM m Source #

A delay list as a Control.Retry policy: retry n waits the n-th delay in microseconds, so the list's length is the retry budget. It paces a bounded run, not an endless loop.