retry v0.9.0 Retry View Source

Provides a convenient interface to retrying behavior. All durations are specified in milliseconds.

Examples

use Retry
import Stream

retry with: exp_backoff |> randomize |> cap(1_000) |> expiry(10_000) do
# interact with external service
end

retry with: lin_backoff(10, @fibonacci) |> cap(1_000) |> take(10) do
# interact with external service
end

retry with: cycle([500]) |> take(10) do
# interact with external service
end

The first retry will exponentially increase the delay, fudging each delay up to 10%, until the delay reaches 1 second and then give up after 10 seconds.

The second retry will linearly increase the retry from 10ms following a Fibonacci pattern giving up after 10 attempts.

The third example shows how we can produce a delay stream using standard Stream functionality. Any stream of integers may be used as the value of with:.

Link to this section Summary

Functions

Retry a block of code delaying between each attempt the duration specified by the next item in the with delay stream

Retry a block of code until halt is emitted delaying between each attempt the duration specified by the next item in the with delay stream

Wait for a block of code to be truthy delaying between each attempt the duration specified by the next item in the delay stream

Link to this section Functions

Link to this macro retry(list1, list2) View Source (macro)

Retry a block of code delaying between each attempt the duration specified by the next item in the with delay stream.

If the block returns any of the atoms specified in atoms, a retry will be attempted. Other atoms or atom-result tuples will not be retried. If atoms is not specified, it defaults to [:error].

Similary, if the block raises any of the exceptions specified in rescue_only, a retry will be attempted. Other exceptions will not be retried. If rescue_only is not specified, it defaults to [RuntimeError].

Example

use Retry
import Stream

retry with: exp_backoff |> cap(1_000) |> expiry(1_000), rescue_only: [CustomError] do
  # interact with external service
end
Link to this macro retry_while(list1, list2) View Source (macro)

Retry a block of code until halt is emitted delaying between each attempt the duration specified by the next item in the with delay stream.

The return value for block is expected to be {:cont, result}, return {:halt, result} to end the retry early.

Example

retry_while with: lin_backoff(500, 1) |> take(5) do
  call_service
  |> case do
    result = %{"errors" => true} -> {:cont, result}
    result -> {:halt, result}
  end
end
Link to this macro wait(stream_builder, clauses) View Source (macro)

Wait for a block of code to be truthy delaying between each attempt the duration specified by the next item in the delay stream.

wait example

use Retry
import Stream

wait exp_backoff |> expiry(1_000) do
  we_there_yet?
end

An optional then block can be given as a continuation which will evaluate only when the do block evaluates to a truthy value.

wait-then example

wait lin_backoff(500, 1) |> take(5) do
  we_there_yet?
then
  {:ok, "We have arrived!"}
end

It’s also possible to specify an else block which evaluates when the do block remains falsy after timeout.

wait-then-else example

wait lin_backoff(500, 1) |> take(5) do
  we_there_yet?
then
  {:ok, "We have arrived!"}
else
  {:error, "We're still on our way :("}
end