Backoff strategies for the :interval option of the waiting macros.
By default, WaitForIt polls at a constant interval. When waiting on an external or struggling
dependency, it is often better to back off — to poll less frequently as time goes on — so that
the dependency is not hammered. The :interval option accepts either a constant number of
milliseconds or a 1-arity function that receives the attempt number (starting at 1) and
returns the number of milliseconds to wait before the next evaluation. The functions in this
module build such interval functions.
The configured timeout still bounds the total wait: the actual sleep before each evaluation is the smaller of the backoff value and the time remaining before the deadline.
Examples
import WaitForIt
# Exponential backoff starting at 50ms, doubling each attempt, capped at 1s, with jitter.
wait(Repo.get(Post, id),
timeout: :timer.seconds(30),
interval: WaitForIt.Backoff.exponential(start: 50, max: 1_000, jitter: 0.1))
Summary
Types
A function that maps an attempt number (starting at 1) to a delay in milliseconds.
Functions
Returns an interval function that always waits the same number of milliseconds.
Returns an interval function implementing exponential backoff.
Types
@type interval_fun() :: (pos_integer() -> non_neg_integer())
A function that maps an attempt number (starting at 1) to a delay in milliseconds.
Functions
@spec constant(non_neg_integer()) :: interval_fun()
Returns an interval function that always waits the same number of milliseconds.
This is equivalent to passing the integer directly as the :interval option, and exists for
symmetry and readability.
@spec exponential(keyword()) :: interval_fun()
Returns an interval function implementing exponential backoff.
The delay for a given attempt is start * factor ^ (attempt - 1), capped at max, with
optional random jitter applied.
Options
:start- the delay (in milliseconds) for the first attempt (default:50):max- the maximum delay (in milliseconds); delays are capped at this value (default:2_000):factor- the multiplier applied for each successive attempt (default:2):jitter- a fraction in the range0.0..1.0controlling random jitter; a value of0.1varies each delay by up to ±10% (default:0.0, i.e. no jitter)
Examples
iex> backoff = WaitForIt.Backoff.exponential(start: 100, factor: 2, max: 1000)
iex> Enum.map(1..5, backoff)
[100, 200, 400, 800, 1000]