mulligan

Crates.iomulligan
lib.rsmulligan
version0.2.0
sourcesrc
created_at2024-10-27 17:11:18.832728
updated_at2024-10-31 01:27:58.323759
descriptionA flexible retry library for Rust async operations with configurable backoff strategies and jitter.
homepagehttps://github.com/theelderbeever/mulligan
repositoryhttps://github.com/theelderbeever/mulligan
max_upload_size
id1424791
size40,068
Taylor Beever (theelderbeever)

documentation

https://docs.rs/mulligan

README

mulligan

A flexible retry library for Rust async operations with configurable backoff strategies and jitter.

Crates.io Documentation

mulligan provides a fluent API for retrying async operations with customizable retry policies, backoff strategies, and jitter. It supports both tokio and async-std runtimes.

Features

  • Multiple backoff strategies:
    • Fixed delay
    • Linear backoff
    • Exponential backoff
  • Configurable jitter options:
    • Full jitter
    • Equal jitter
    • Decorrelated jitter
  • Maximum retry attempts
  • Maximum delay caps
  • Custom retry conditions
  • Async runtime support:
    • tokio (via tokio feature)
    • async-std (via async-std feature)

Quick Start

use std::time::Duration;

async fn fallible_operation(msg: &str) -> std::io::Result<()> {
    // Your potentially failing operation here
    Err(std::io::Error::other(msg))
}

#[tokio::main]
async fn main() {
    let result = mulligan::until_ok()
        .stop_after(5)                     // Try up to 5 times
        .max_delay(Duration::from_secs(3)) // Cap maximum delay at 3 seconds
        .exponential(Duration::from_secs(1)) // Use exponential backoff
        .full_jitter()                     // Add randomized jitter
        .retry(|| async {
            fallible_operation("connection failed").await
        })
        .await;
}

Alternatively, you may provide a custom stopping condition. mulligan::until_ok() is equivalent to the custom stopping condition shown below.

#[tokio::main]
async fn main() {
    let result = mulligan::until(|res| res.is_ok())
        .stop_after(5)                     // Try up to 5 times
        .max_delay(Duration::from_secs(3)) // Cap maximum delay at 3 seconds
        .exponential(Duration::from_secs(1)) // Use exponential backoff
        .full_jitter()                     // Add randomized jitter
        .on_retry(|prev, attempts| {       // Run before each retry.
            println!("In the {}-th attempt, the returned result is {:?}.", attempts, prev);
            println!("Start next attempt");
        })
        .retry(|| async {
            fallible_operation("connection failed").await
        })
        .await;
}

Installation

Add this to your Cargo.toml:

[dependencies]
mulligan = { version = "0.1", features = ["tokio"] } # or ["async-std"]
Commit count: 25

cargo fmt