Calls a function again when it fails.
A retry is declared in a module that uses Rexsilient:
defmodule MyApp.Resilience do
use Rexsilient
alias Rexsilient.Retry.Strategy
retry :payments do
attempts 4
strategy Strategy.Exponential, base_delay: 100, max_delay: 5_000, jitter: :full
end
endand used with @retry :payments from Rexsilient.Decorator:
defmodule MyApp.Payments do
use Rexsilient.Decorator
@retry :payments
def charge(order) do
PaymentsClient.charge(order)
end
endor, without a decorator, with run/2:
Rexsilient.Retry.run(:payments, fn -> PaymentsClient.charge(order) end)Settings
attempts- the total number of calls, the first one included. A positive integer, or:infinityto leave the limit to the strategy. Required.strategy- the module that decides how long to wait before the next attempt, or to stop, and its options. Required. SeeRexsilient.Retry.Strategy.classify_with- the name of the functions, in the declaring module, that decide which outcomes are failures and so are retried. Defaults toclassify; seeRexsilient.Classify.
Behaviour
The function is called. If its outcome is a success, it is returned. If it is a failure and attempts remain, the strategy is asked for a delay, the caller sleeps for it, and the function is called again.
When no attempts remain, or the strategy stops, the last outcome is returned unchanged: the value the function returned, or what it raised, threw or exited with, re-raised with its original stacktrace.
{:error, :circuit_open} is never retried: a circuit breaker just said the
dependency is down, and retrying would only wait for the same answer. It is
a failure whatever classify says, and it ends the run at once.
The delay runs in the calling process, with Process.sleep/1.
What is retried by default
The default classify counts every {:error, _} and every raise, throw
and exit as a failure, so all of them are retried. That includes bugs,
such as a FunctionClauseError, which then crash only after every
attempt and its delay. It also includes calls that are not idempotent
and may have taken effect before failing. Use classify_with to retry
only the failures that are safe and worth retrying.
Summary
Functions
Calls func through the retry name.
Types
@type name() :: atom()
The name a retry is declared with.
Functions
Calls func through the retry name.
Returns the outcome of the last attempt; see Behaviour.
Raises ArgumentError if no retry is registered under name.
Examples
Rexsilient.Retry.run(:payments, fn -> Payments.charge(order) end)