Skip to main content

vela_protocol/
retry.rs

1//! Retry with exponential backoff for transient network failures.
2
3use std::time::Duration;
4use tokio::time::sleep;
5
6/// Retry an async operation with exponential backoff.
7/// Retries up to `max_retries` times with delays of 1s, 2s, 4s, 8s.
8/// Only retries on errors, not on successful-but-wrong results.
9pub async fn retry_with_backoff<F, Fut, T, E>(
10    label: &str,
11    max_retries: u32,
12    mut operation: F,
13) -> Result<T, E>
14where
15    F: FnMut() -> Fut,
16    Fut: std::future::Future<Output = Result<T, E>>,
17    E: std::fmt::Display,
18{
19    let mut attempt = 0;
20    loop {
21        match operation().await {
22            Ok(val) => return Ok(val),
23            Err(e) => {
24                attempt += 1;
25                if attempt > max_retries {
26                    return Err(e);
27                }
28                let delay = Duration::from_secs(1 << (attempt - 1)); // 1s, 2s, 4s, 8s
29                eprintln!(
30                    "  [retry] {} failed (attempt {}/{}): {}. Retrying in {:?}...",
31                    label, attempt, max_retries, e, delay
32                );
33                sleep(delay).await;
34            }
35        }
36    }
37}