Crate backon

source ·
Expand description

Build Status Latest Version

BackON

Make retry like a built-in feature provided by Rust.

  • Simple: Just like a built-in feature: your_fn.retry(ExponentialBuilder::default()).await.
  • Flexible: Supports both blocking and async functions.
  • Powerful: Allows control over retry behavior such as when and notify.
  • Customizable: Supports custom retry strategies like exponential, constant, etc.

§Backoff

Retry in BackON requires a backoff strategy. BackON will accept a BackoffBuilder which will generate a new Backoff for each retry.

BackON provides several backoff implementations with reasonable defaults:

§Sleep

Retry in BackON requires an implementation for sleeping. BackON will accept a Sleeper to pause for a specified duration.

BackON employs the following default sleep implementations:

  • tokio-sleep: Utilizes TokioSleeper within a Tokio context in non-wasm32 environments.
  • gloo-timers-sleep: Utilizes [GlooTimersSleep] to pause in wasm32 environments.

Users CAN provide a custom implementation if they prefer not to use the default options.

If neither feature is enabled nor a custom implementation is provided, BackON will fallback to an empty sleeper. This will cause a panic in the debug profile and do nothing in the release profile.

§Retry

For additional examples, please visit docs::examples.

§Retry an async function

use anyhow::Result;
use backon::ExponentialBuilder;
use backon::Retryable;
use core::time::Duration;

async fn fetch() -> Result<String> {
    Ok("hello, world!".to_string())
}

#[tokio::main]
async fn main() -> Result<()> {
    let content = fetch
        // Retry with exponential backoff
        .retry(ExponentialBuilder::default())
        // Sleep implementation, default to tokio::time::sleep if `tokio-sleep` has been enabled.
        .sleep(tokio::time::sleep)
        // When to retry
        .when(|e| e.to_string() == "EOF")
        // Notify when retrying
        .notify(|err: &anyhow::Error, dur: Duration| {
            println!("retrying {:?} after {:?}", err, dur);
        })
        .await?;
    println!("fetch succeeded: {}", content);

    Ok(())
}

§Retry a blocking function

use anyhow::Result;
use backon::BlockingRetryable;
use backon::ExponentialBuilder;
use core::time::Duration;

fn fetch() -> Result<String> {
    Ok("hello, world!".to_string())
}

fn main() -> Result<()> {
    let content = fetch
        // Retry with exponential backoff
        .retry(ExponentialBuilder::default())
        // When to retry
        .when(|e| e.to_string() == "EOF")
        // Notify when retrying
        .notify(|err: &anyhow::Error, dur: Duration| {
            println!("retrying {:?} after {:?}", err, dur);
        })
        .call()?;
    println!("fetch succeeded: {}", content);

    Ok(())
}

Re-exports§

  • pub use constant::ConstantBackoff;
  • pub use fibonacci::FibonacciBackoff;
  • pub use exponential::ExponentialBackoff;

Modules§

Structs§

Traits§

Type Aliases§

  • The default implementation of Sleeper while feature std-blocking-sleep enabled.
  • The default implementation of Sleeper while feature tokio-sleep enabled.