Skip to content

JosephTLyons/persevero

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

98 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

persevero

Package Version Hex Docs

Execute fallible operations multiple times.

Installation

gleam add persevero@1

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.debug("Give me #prawducks. 😃")
    _ -> io.debug("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.debug("Give me #prawducks. 😃")
    _ -> io.debug("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.

About

Execute fallible operations multiple times.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages