Normandy.Resilience.Retry (normandy v0.2.0)
View SourceRetry mechanism with exponential backoff for handling transient failures.
Provides configurable retry logic for operations that may fail temporarily, such as network requests, API calls, or resource access.
Features
- Exponential backoff with jitter
- Configurable retry limits
- Custom retry conditions
- Detailed error tracking
Example
# Basic retry with defaults
Retry.with_retry(fn ->
MyAPI.call()
end)
# Custom retry configuration
Retry.with_retry(
fn -> MyAPI.call() end,
max_attempts: 5,
base_delay: 1000,
max_delay: 30_000,
retry_on: [:network_error, :rate_limit]
)
# With custom retry condition
Retry.with_retry(
fn -> MyAPI.call() end,
retry_if: fn error ->
match?({:error, :temporary}, error)
end
)
Summary
Types
@type retry_option() :: {:max_attempts, pos_integer()} | {:base_delay, pos_integer()} | {:max_delay, pos_integer()} | {:backoff_factor, float()} | {:jitter, boolean()} | {:retry_on, [atom()]} | {:retry_if, (term() -> boolean())}
@type retry_options() :: [retry_option()]
Functions
@spec preset(atom()) :: retry_options()
Create a retry configuration for common scenarios.
Presets
:quick- Fast retries for quick operations (2 attempts, 100ms base):standard- Default configuration (3 attempts, 1s base):persistent- More aggressive retries (5 attempts, 1s base):patient- Long-running retries (10 attempts, 2s base)
Examples
Retry.with_retry(fn -> api_call() end, Retry.preset(:persistent))
@spec with_retry(function(), retry_options()) :: {:ok, term()} | {:error, {term(), pos_integer(), [term()]}}
Execute a function with retry logic.
Options
:max_attempts- Maximum number of attempts (default: 3):base_delay- Initial delay in milliseconds (default: 1000ms):max_delay- Maximum delay in milliseconds (default: 32000ms):backoff_factor- Exponential backoff multiplier (default: 2.0):jitter- Add randomness to delays (default: true):retry_on- List of error types to retry on (default: network errors, timeouts, rate limits):retry_if- Custom retry condition function
Returns
{:ok, result}- Success after 1 or more attempts{:error, {reason, attempts, errors}}- Failed after all attempts
Examples
# Retry with defaults
{:ok, result} = Retry.with_retry(fn ->
{:ok, perform_operation()}
end)
# Custom configuration
{:ok, result} = Retry.with_retry(
fn -> risky_operation() end,
max_attempts: 5,
base_delay: 500
)
# Custom retry condition
Retry.with_retry(
fn -> custom_call() end,
retry_if: fn
{:error, %{status: status}} when status >= 500 -> true
_ -> false
end
)