Skip to main content

basic_retry/
basic_retry.rs

1//! Sync retry: retry only temporary failures, with a user-provided sleeper.
2//!
3//! Run with: `cargo run -p reliakit-retry --example basic_retry`
4
5use core::time::Duration;
6
7use reliakit_retry::{retry_with_sleep, Backoff, RetryError, RetryPolicy};
8
9#[derive(Debug)]
10enum ApiError {
11    /// A transient failure worth retrying.
12    Temporary,
13    /// A permanent failure; retrying will not help.
14    Fatal,
15}
16
17fn main() {
18    let policy = RetryPolicy::new(
19        5,
20        Backoff::exponential(Duration::from_millis(50), 2).with_max_delay(Duration::from_secs(1)),
21    )
22    .expect("max_attempts is non-zero");
23
24    // An operation that fails twice with a temporary error, then succeeds.
25    let mut attempt = 0;
26    let result: Result<&str, RetryError<ApiError>> = retry_with_sleep(
27        &policy,
28        || {
29            attempt += 1;
30            println!("attempt {attempt}");
31            if attempt < 3 {
32                Err(ApiError::Temporary)
33            } else {
34                Ok("payload")
35            }
36        },
37        |error| matches!(error, ApiError::Temporary), // retry only temporary errors
38        |delay| {
39            // You provide the waiting. In real code, call your platform or
40            // runtime sleep here; this example only reports the delay so it
41            // stays dependency-free and instant.
42            println!("  would wait {delay:?} before the next attempt");
43        },
44    );
45    match result {
46        Ok(body) => println!("succeeded with: {body}"),
47        Err(error) => println!("gave up: {error:?}"),
48    }
49
50    // A fatal error stops immediately, even though attempts remain.
51    let mut attempt = 0;
52    let result: Result<&str, RetryError<ApiError>> = retry_with_sleep(
53        &policy,
54        || {
55            attempt += 1;
56            Err(ApiError::Fatal)
57        },
58        |error| matches!(error, ApiError::Temporary),
59        |_delay| {},
60    );
61    println!(
62        "fatal path: stopped after {} attempt(s)",
63        result.unwrap_err().attempts()
64    );
65}