#retry #tokio #async #async-await #io-error

retry_fn

A simple retry function with versions for blocking or non-blocking, tokio or async-std

2 unstable releases

0.2.0 Jan 26, 2021
0.1.0 Nov 24, 2020

#1384 in Asynchronous

MIT license

29KB
493 lines

retry_fn

Build Status Crate API

Function for executing retry either as a closure with a std-based sleep (thread::sleep) or using either of the most popular async runtime's. Tokio or async-std. Inspired by the other retry libraries out there, the desire is to keep this up-to-date and combine features from several.

Sync Example

use std::{io, time::Duration};
use retry_fn::{retry, RetryResult, strategy::ExponentialBackoff};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut count = 0;
    let res = retry(ExponentialBackoff::new(Duration::from_secs(2)), |op| {
       if op.retries >= 3 {
           RetryResult::<&str, _>::Err(io::Error::new(
               io::ErrorKind::TimedOut,
               "timed out",
           ))
       } else {
           count += 1;
           RetryResult::Retry()
       }
    });
    assert_eq!(count, 3);
    assert!(res.is_err());
    Ok(())
}

Using tokio

Enable the tokio-runtime feature to get access to this function

use std::{io, sync::{Arc, Mutex}};
use retry_fn::{tokio::retry, RetryResult, strategy::Constant};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let count: Arc<Mutex<i32>> = Arc::new(Mutex::new(0));
    let res = retry(Constant::from_millis(100), |op| {
        let count = count.clone();
        async move {
            if op.retries >= 3 {
                RetryResult::<&str, _>::Err(io::Error::new(
                    io::ErrorKind::TimedOut,
                    "timed out",
                ))
            } else {
                *count.lock().unwrap() += 1;
                RetryResult::Retry()
            }
        }
    })
    .await;
    assert_eq!(*count.lock().unwrap(), 3);
    assert!(res.is_err());
    Ok(())
}

Dependencies

~0–10MB
~107K SLoC