Conduit.Backoff
Conduit.Backoff — retry delay strategies.
Each strategy maps (attempt : Int) to a delay in milliseconds. "attempt" is the 1-based retry count: attempt=1 is the first retry after the initial failure, attempt:2 is the second, etc.
The internal Conduit.Backoff type uses constructor names prefixed with "Conduit" (ConduitLinear, ConduitExponential, etc.) so they do not clash with march stdlib types (Backoff, QuantileMethod) that share the plain names.
Public API: Conduit.Backoff.exponential() — value alias for ConduitExponential Conduit.Backoff.fibonacci() — value alias for ConduitFibonacci Conduit.Backoff.linear_strat() — function returning ConduitLinear (named linear_strat because linear is a reserved March keyword) Conduit.Backoff.custom(f) — wrap a user Int -> Int function
Caps ───── Exponential and Fibonacci delays are capped at max_delay_ms (24 hours) to prevent arithmetic overflow and to keep retry windows reasonable. If a Custom function returns a value above the cap, it is not clamped — the caller is responsible for capping custom delays.
Linear has no cap; it grows at 5 s/attempt and stays manageable for normal max_attempts values (≤ 25 attempts → ≤ 125 s).
Functions
Create a custom backoff strategy from a user-supplied function.
`f` receives the 1-based attempt number and must return a non-negative
integer of milliseconds. Example:
let my_backoff = Conduit.Backoff.custom(fn att -> att * 2000)Compute the retry delay in milliseconds for the given strategy and attempt.
Strategies:
linear — 5 000 * attempt ms (5 s, 10 s, 15 s, …)
exponential — 2^(attempt-1) * 1 000 ms (1 s, 2 s, 4 s, …), capped at 24 h
fibonacci — fib(attempt) * 1 000 ms (1 s, 1 s, 2 s, 3 s, 5 s, …), capped at 24 h
custom(f) — f(attempt); the returned value is used as-is (ms)Return the serialised name for a Backoff strategy.