elixir_retry v0.5.0 Retry

Provides a convenient interface to retrying behavior. All durations a 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:.

Summary

Macros

Retry a block of code with a exponential backoff delay between attempts

Retry a block of code a maximum number of times with a fixed delay between attempts

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 with delay stream

Macros

backoff(time_budget, list)

Retry a block of code with a exponential backoff delay between attempts.

Example

backoff 1000, delay_cap: 100 do
# interact with external service
end

Runs the block repeated until it succeeds or 1 second elapses with an exponentially increasing delay between attempts. Execution is deemed a failure if the block returns {:error, _} or raises a runtime error.

The delay_cap is optional. If specified it will be the max duration of any delay. In the example this is saying never delay more than 100ms between attempts. Omitting delay_cap is the same as setting it to :infinity.

retry(arg1, arg2)

Retry a block of code a maximum number of times with a fixed delay between attempts.

Example

retry 5 in 500 do
# interact with external service
end

Runs the block up to 5 times with a half second sleep between each attempt. Execution is deemed a failure if the block returns {:error, _} or raises a runtime error.

retry_while(list1, list2)

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
wait(list1, list2)

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

Example

use Retry
import Stream

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