attempt v0.6.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(function(), Keyword.t() | Attempt.Retry.Budget.t()) :: any()
Run a function in the context of a retry budget.
A retry budget has several compoents:
a
token bucketwhich acts to provide retry throttlnh for any retriesa
retry policywhich determines whether to return, retry or reraisea
backoffstrategy which determines the retry backoff strategya maximum number of allowable
triesthat 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
funis an anonymous function or function reference to be executed.optionsis a keyword list of options to configure the retry budget
Options
:triesis the number of times the function will be executed if an error is returned from the function:token_bucketis the token bucket used to throttle the execution rate. Currently only one token bucket is implemented. SeeAttempt.Bucket.Token:retry_policyis a module that implements theAttempt.Retrybehaviour to classify the return value from thefunas either:return,:retryorreraise. The defaultretry_policyisAttempt.Retry.DefaultPolicy.:backoffis a module that implements theAttempt.Retry.Backoffbehaviour which is used to determine the backoff strategy for retries.
Default options
If not supplied the default options are:
:triesis1:token_bucketisAttempt.Bucket.Token.new(@default_bucket_name):retry_policyisAttempt.Retry,Policy.Default:backoffisAttempt.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:
:returnmeans that the return value of the function is considered a success and it returned to the called:retrymeans that a failure return was detected but that the failure is considered transient and is therefore eligble to be retried:reraisemeans 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]}}}