persevero
Execute fallible operations multiple times.
Installation
gleam add persevero
Usage
A simple example:
import gleam/http/request
import gleam/httpc
import gleam/io
import persevero
pub fn main() {
let assert Ok(request) = request.to("https://www.apple.com")
let response = {
use <- persevero.execute(
wait_stream: persevero.exponential_backoff(50, 2),
allow: persevero.all_errors,
mode: persevero.MaxAttempts(3),
)
httpc.send(request)
}
case response {
Ok(response) if response.status == 200 ->
io.println("Give me #prawducks. ๐")
_ -> io.println("Guess I'll dev on Linux. ๐")
}
}
A ridiculous example:
import gleam/http/request
import gleam/httpc
import gleam/io
import persevero
pub fn main() {
let assert Ok(request) = request.to("https://www.apple.com")
let response =
persevero.custom_backoff(wait_time: 1000, next_wait_time: fn(previous) {
{ previous + 100 } * 2
})
|> persevero.apply_multiplier(3)
|> persevero.apply_jitter(20)
|> persevero.apply_cap(10_000)
|> persevero.apply_constant(7)
|> persevero.execute(
allow: fn(error) {
case error {
httpc.InvalidUtf8Response -> True
_ -> False
}
},
mode: persevero.MaxAttempts(10),
operation: fn() { httpc.send(request) },
)
case response {
Ok(response) if response.status == 200 ->
io.println("Give me #prawducks. ๐")
_ -> io.println("Guess I'll dev on Linux. ๐")
}
}
Instead of defining a maximum number of attempts, you can use an expiry mode. This will cause the operation to cease retrying after a specified duration.
use <- persevero.execute(
wait_stream: persevero.constant_backoff(100),
allow: persevero.all_errors,
mode: persevero.Expiry(10_000),
)
Use raw yielders for
ultimate wait stream manipulation:
use <- persevero.execute(
wait_stream: yielder.repeat(5)
|> yielder.intersperse(10)
|> yielder.cycle,
allow: persevero.all_errors,
mode: persevero.MaxAttempts(100),
)
Note that persevero generates a final wait stream with an initial 0 value, in
the execute function, after all transformations to the stream have been
applied, so the first attempt will never sleep. You do not need to account for
this in your custom wait stream.
Targets
persevero supports the Erlang target.
Inspiration
The feature set, and some of the design, is inspired by the
retry library for Elixir.