partisan_retry (partisan v5.0.1)
View SourceOverview
This module implements a structured retry mechanism with optional exponential backoff and deadline tracking, designed for reliable asynchronous retries. It wraps the Backoff library.
Key Features
- Supports a fixed retry interval or exponential backoff.
- Tracks retry attempts (
count
) and enforces a maximum retry limit. - Optional global deadline (in milliseconds) for all retries.
- Integrates with
erlang:start_timer/3
to fire retries after delay.
Record Structure
#partisan_retry{}
contains retry state, including:id
: Identifier associated with the retry (e.g., message ID).deadline
: Absolute time limit in ms (from start) before giving up.max_retries
: Maximum allowed retry attempts.interval
: Default interval between retries (in ms).count
: Current number of failed attempts.backoff
: Optional backoff state (using externalbackoff
module).start_ts
: Start timestamp (used for deadline tracking).
Retry Configuration Options (init/2)
Can be supplied as a proplist or map:
{deadline, pos_integer()}
- Absolute time limit in milliseconds for all retries.{max_retries, pos_integer()}
- Max number of retry attempts.backoff
{enabled, boolean()}
- Enables exponential backoff.{min, pos_integer()}
- Minimum backoff duration.{max, pos_integer()}
- Maximum backoff duration.{type, jitter | normal}
- Type of backoff strategy.
Usage Example
{Delay, Retry1} = partisan_retry:fail(Retry0),
Ref = partisan_retry:fire(Retry1).
Return Semantics
Functions like get/1
and fail/1
return either the next delay (in ms) or
an atom indicating termination conditions: max_retries
or deadline
.
Integration Notes
Summary
Functions
Returns the number of failed retry attempts so far.
Increments the retry counter and computes the next delay.
Starts a timer based on the current retry delay.
Returns the delay (in milliseconds) before the next retry should occur.
Initializes a new retry state with the given ID and options.
Resets the retry counter and (if applicable) resets the backoff state.
Types
-type backoff_opts() :: #{enabled => boolean(), min => pos_integer(), max => pos_integer(), type => jitter | normal}.
-type optional(T) :: T | undefined.
-type opts() :: #{deadline => non_neg_integer(), max_retries => non_neg_integer(), interval => pos_integer(), backoff => backoff_opts()}.
-type t() :: #partisan_retry{id :: any(), deadline :: non_neg_integer(), max_retries :: non_neg_integer(), interval :: pos_integer(), count :: non_neg_integer(), backoff :: optional(backoff:backoff()), start_ts :: optional(pos_integer())}.
Functions
-spec count(State :: t()) -> non_neg_integer().
Returns the number of failed retry attempts so far.
-spec fail(State :: t()) -> {Time :: integer(), NewState :: t()} | {deadline | max_retries, NewState :: t()}.
Increments the retry counter and computes the next delay.
If max_retries
is reached, returns {max_retries, State}
.
If a deadline is exceeded, get/1
will later return deadline
.
Automatically initializes the start timestamp on first retry.
Returns the tuple {Delay, NewState}
, or {max_retries | deadline, NewState}
.
Starts a timer based on the current retry delay.
If the retry has expired (due to max retries or deadline), this function raises an error.
Returns the timer reference if successful; otherwise, throws max_retries
or deadline
error.
Returns the delay (in milliseconds) before the next retry should occur.
If no retries remain (max_retries
) or the deadline has passed, returns
max_retries
or deadline
respectively.
Returns integer()
if retry is allowed, or deadline | max_retries
atom.
Initializes a new retry state with the given ID and options.
The retry mechanism can be based on a fixed interval or use exponential backoff depending on options.
Set deadline
to 0 to disable deadline tracking and rely solely on max_retries
.
Resets the retry counter and (if applicable) resets the backoff state.
Used after a successful attempt to stop retrying.
Returns the tuple of {Delay, NewState}
where delay is the base interval or backoff.