attempt v0.4.0 Attempt
Link to this section Summary
Link to this section Functions
Implements a block form of Attempt.run/2
.
Examples
iex> require Attempt
...> Attempt.execute tries: 3 do
...> IO.puts "Welcome to Attempt"
...> end
Hi
:ok
Run a function in the context of a retry budget.
A retry budget has several compoents:
a
token bucket
which acts to provide retry throttlnh for any retriesa
retry policy
which determines whether to return, retry or reraisea
backoff
strategy which determines the retry backoff strategya maximum number of allowable
tries
that are performed when in an effort to generate a non-error return
The given function will be executed until a successful return is delivered or the maximum number of tries is exceeded or if no token could be claimed.
Arguments
fun
is an anonymous function or function reference to be executed.options
is a keyword list of options to configure the retry budget
Options
:tries
is the number of times the function will be executed if an error is returned from the function:token_bucket
is the token bucket used to throttle the execution rate. Currently only one token bucket is implemented. SeeAttempt.Bucket.Token
:retry_policy
is a module that implements theAttempt.Retry
behaviour to classify the return value from thefun
as either:return
,:retry
orreraise
. The defaultretry_policy
isAttempt.Retry.DefaultPolicy
.:backoff
is a module that implements theAttempt.Retry.Backoff
behaviour which is used to determine the backoff strategy for retries.
Default options
If not supplied the default options are:
:tries
is1
:token_bucket
isAttempt.Bucket.Token.new(@default_bucket_name)
:retry_policy
isAttempt.Retry,Policy.Default
:backoff
isAttempt.Retry.Backoff.Exponential
Retry policy actions
In order to ascertain whether a function should be retried each return value
needs to be classified. The classification is the responsibility of the
:retry_policy
module. Three classifications are available:
:return
means that the return value of the function is considered a success and it returned to the called:retry
means that a failure return was detected but that the failure is considered transient and is therefore eligble to be retried:reraise
means that an exception was detected and the execption is not considered transient. Therefore the exception should be re-raised.
See also Attempt.Retry.Exception
which defines a protocol for determining
the classification of exceptions and Attempt.Retry.DefaultPolicy
which
implements the default classifier.
Examples
iex#> Attempt.run fn -> "Hello World" end
"Hello World"
iex#> Attempt.run fn -> IO.puts "Reraise Failure!"; div(1,0) end, tries: 3
Reraise Failure!
** (ArithmeticError) bad argument in arithmetic expression
:erlang.div(1, 0)
(attempt) lib/attempt.ex:119: Attempt.execute_function/1
(attempt) lib/attempt.ex:98: Attempt.execute/6
iex#> Attempt.run fn -> IO.puts "Try 3 times"; :error end, tries: 3
Try 3 times
Try 3 times
Try 3 times
:error
# Create a bucket that adds a new token only every 10 seconds
iex#> {:ok, bucket} = Attempt.Bucket.Token.new :test, fill_rate: 10_000
iex#> Attempt.run fn ->
IO.puts "Try 11 times and we'll timeout claiming a token"
:error
end, tries: 11, token_bucket: bucket
Try 11 times and we'll timeout claiming a token
Try 11 times and we'll timeout claiming a token
Try 11 times and we'll timeout claiming a token
Try 11 times and we'll timeout claiming a token
Try 11 times and we'll timeout claiming a token
Try 11 times and we'll timeout claiming a token
Try 11 times and we'll timeout claiming a token
Try 11 times and we'll timeout claiming a token
Try 11 times and we'll timeout claiming a token
Try 11 times and we'll timeout claiming a token
{:error, {:timeout, {GenServer, :call, [:test, :claim_token, 5000]}}}