use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
use std::time::Duration;
use mettle::blocking::retry;
use mettle::{ExponentialBackoff, ExponentialBackoffConfig};
#[derive(Debug)]
enum FetchError {
Timeout, NotFound, }
fn main() {
let result = retry(flaky_fetch).call();
println!("1. defaults: {result:?}");
let result = retry(always_404)
.when(|e| matches!(e, FetchError::Timeout))
.call();
println!("2. filtered: {result:?}");
let result = retry(flaky_fetch)
.backoff(fast_backoff())
.max_elapsed(Duration::from_secs(5))
.when(|e| matches!(e, FetchError::Timeout))
.call();
println!("3. full: {result:?}"); }
fn flaky_fetch() -> Result<&'static str, FetchError> {
static ATTEMPTS: AtomicUsize = AtomicUsize::new(0);
if ATTEMPTS.fetch_add(1, SeqCst) < 2 {
Err(FetchError::Timeout)
} else {
ATTEMPTS.store(0, SeqCst);
Ok("user data")
}
}
fn always_404() -> Result<&'static str, FetchError> {
Err(FetchError::NotFound)
}
fn fast_backoff() -> ExponentialBackoff {
ExponentialBackoff::new(ExponentialBackoffConfig {
base: Duration::from_millis(20),
..Default::default()
})
.expect("backoff config is valid")
}