Crate asyn_retry_policy

Crate asyn_retry_policy 

Source
Expand description

A small crate providing an async retry policy with exponential backoff and jitter.

Example: programmatic and macro usage (predicate-aware)

use asyn_retry_policy::RetryPolicy;
use std::time::Duration;
use std::sync::{Arc, atomic::{AtomicU8, Ordering}};

// Programmatic usage with a predicate that inspects the error type (`String` here)
#[tokio::main]
async fn main() {
    // predicate gets an `&E`, so when `E = String` it's `&String`.
    fn is_retryable(e: &String) -> bool { e == "temporary" }

    let mut policy = RetryPolicy::default();
    policy.attempts = 5;
    policy.jitter = false;

    let tries = Arc::new(AtomicU8::new(0));
    let res = policy.retry(
        {
            let tries = tries.clone();
            move || {
                let tries = tries.clone();
                async move {
                    let prev = tries.fetch_add(1, Ordering::SeqCst);
                    if prev < 2 { Err::<u8, _>(String::from("temporary")) } else { Ok(0u8) }
                }
            }
        },
        is_retryable,
    ).await;
    assert!(res.is_ok());
}

Macro usage examples (predicate path and inline closure):

use asyn_retry_policy::retry;
use std::sync::{Arc, atomic::{AtomicU8, Ordering}};

fn should_retry(e: &String) -> bool { e == "tmp" }

#[retry(attempts = 3, predicate = should_retry)]
async fn my_endpoint(tries: Arc<AtomicU8>) -> Result<u8, String> {
    let prev = tries.fetch_add(1, Ordering::SeqCst);
    if prev < 2 { Err(String::from("tmp")) } else { Ok(7u8) }
}

Inline closure predicate example:

use asyn_retry_policy::retry;
use std::sync::{Arc, atomic::{AtomicU8, Ordering}};

#[retry(predicate = |e: &String| e == "tmp")]
async fn my_endpoint_closure(tries: Arc<AtomicU8>) -> Result<u8, String> {
    let prev = tries.fetch_add(1, Ordering::SeqCst);
    if prev < 2 { Err(String::from("tmp")) } else { Ok(8u8) }
}

Structs§

RetryPolicy
Retry policy configuration

Attribute Macros§

retry