Retry with exponential backoff and optional jitter.
Example
Apero.Retry.with(
fn -> HTTPoison.get(url) end,
max_attempts: 5,
base_delay: 100,
max_delay: 5_000,
retry_on: fn
{:ok, %{status: status}} when status >= 500 -> true
{:error, %HTTPoison.Error{reason: :timeout}} -> true
_ -> false
end
)
Summary
Functions
Handles a {:apero_retry, ...} message produced by schedule_next/7.
Runs the next attempt; if it succeeds or exhausts retries, returns the
result via {:apero_retry_done, result}. Otherwise schedules the
next retry.
Non-blocking variant of with/2 that uses Process.send_after between
attempts instead of Process.sleep.
Types
Functions
@spec handle_message( {:apero_retry, (-> any()), integer(), integer(), integer(), integer(), (any() -> boolean()), (-> any())} ) :: any()
Handles a {:apero_retry, ...} message produced by schedule_next/7.
Runs the next attempt; if it succeeds or exhausts retries, returns the
result via {:apero_retry_done, result}. Otherwise schedules the
next retry.
This is the GenServer hook for non-blocking retry.
@spec schedule_next( (-> any()), integer(), integer(), integer(), integer(), (any() -> boolean()), (-> any()) ) :: :ok
Non-blocking variant of with/2 that uses Process.send_after between
attempts instead of Process.sleep.
Caveats
Because the retry is driven by the calling process's mailbox, this
helper must be called from a process that can receive messages
(typically a GenServer). The calling process should be ready to
receive the {:apero_retry_continue, fun, state} message; in practice
this helper is best used from a custom handle_info/2 that calls
the next attempt and sends itself another message after the delay.
Most consumers should prefer the simpler with/2 (which uses
Process.sleep) unless they are calling from a GenServer mailbox
loop.