retryable_ex v2.0.0 Retryable
Simple code retrying without metaprogramming.
A simple example...
Retryable.retryable [on: TimeoutError, tries: 5, sleep: 2], fn ->
SomeApi.call
end
You can configure the defaults with Mix.Config
...
use Mix.Config
config :retryable_ex, :defaults,
tries: 10,
sleep: fn n -> :math.pow(2, n) end
You can make named configurations to be used later...
use Mix.Config
config :retryable_ex, :aws,
message: ["timeout", ~r/throttling/i]
tries: 5,
sleep: 2
Retryable.retryable(:aws, fn -> make_aws_call() end)
Link to this section Summary
Types
Function to run exactly once (similar to after
in a try
block)
What number retry we're on. Zero based (first retry is 0)
Exception message(s) to retry on
What to retry on (exceptions or :error)
options
for retryable
Time in seconds to sleep between retries
How many times to retry
Functions
Maybe retry some code
Link to this section Types
after_fn()
after_fn() :: (() -> any())
after_fn() :: (() -> any())
Function to run exactly once (similar to after
in a try
block).
count()
count() :: integer()
count() :: integer()
What number retry we're on. Zero based (first retry is 0).
message()
Exception message(s) to retry on.
If message is a string, then substring matching is used.
on()
What to retry on (exceptions or :error).
options()
options
for retryable.
Time in seconds to sleep between retries.
tries()
tries() :: integer()
tries() :: integer()
How many times to retry.
Link to this section Functions
retryable(options \\ [], func)
Maybe retry some code.
Return value is that of the given function.
Options
on
: Retry on exception or:error
. Can be a list. Default[]
(retry on any exception)message
: Only retry if exception message matches. Default[]
(retry on any message)tries
: How many times to retry. Default1
sleep
: How long to sleep (in seconds) between retries. Can be a function. Default:1
after
: Code to run (exactly once) no matter how many retries (zero or more). Default:nil
See the types in this module for exact specifications of the options
.
When :message
is specified the =~
operator is used (e.g. regex or string contains).
Named config
You can set defaults and named configurations.
use Mix.Config
config :retryable_ex, :defaults,
on: ArgumentError
config :retryable_ex, :my_config,
tries: 10
# Both these calls have the same effect.
retryable(:my_config, fn -> ... end)
retryable([on: ArgumentError, tries: 10], fn -> ... end)
On error
When you use the [on: error]
option, the following return values will cause a retry:
:error
{:error, reason}
{:error, reason, ...}
- i.e. any tuple where the first element is
:error
You can customize the shape that defines an error with a function:
error_shape = fn
:error -> true
:failure -> true
{:error, _reason} -> true
{:failure, _reason} -> true
_ -> false
end
retryable([on: {:error, error_shape}], fn ->
case SomeModue.some_function do
:failure = result -> result # Will cause retry
{:ok, value} = result -> result # Will not cause retry
end
end)
Examples
Retry on specific exception(s):
retryable([on: ArgumentError], fn -> ... end)
retryable([on: [ArgumentError, ArithmeticError]], fn -> ... end)
Retry on a specific exception message(s):
retryable([message: "some substring"], fn -> ... end)
retryable([message: ~r/some regex/], fn -> ... end)
retryable([message: ["foo", ~r/bar/]], fn -> ... end)
Retry on error:
result = retryable [on: :error], fn ->
case something() do
{:ok, _} = result -> result # Success, don't retry
{:error, _} = result -> result # Error, do retry
end
end
Retry on error or exception:
result = retryable [on: [:error, ArgumentError]], fn ->
case something() do
{:ok, _} = result -> {:ok, result} # Success, don't retry
{:error, _} = result -> {:error, result} # Error, do retry
end
end
Retry with exponential backoff:
retryable [sleep: &(:math.pow(2, &1))], fn -> ... end