tests_fuzz/utils/
retry.rs1use std::future::Future;
16use std::time::Duration;
17
18use common_telemetry::warn;
19
20pub async fn retry_with_backoff<T, E, Fut, F>(
21 mut operation: F,
22 max_attempts: usize,
23 init_backoff: Duration,
24 max_backoff: Duration,
25) -> Result<T, E>
26where
27 F: FnMut() -> Fut,
28 Fut: Future<Output = Result<T, E>>,
29 E: std::fmt::Debug,
30{
31 let mut backoff = init_backoff;
32 for attempt in 0..max_attempts {
33 match operation().await {
34 Ok(result) => return Ok(result),
35 Err(err) if attempt + 1 == max_attempts => return Err(err),
36 Err(err) => {
37 let current_attempt = attempt + 1;
38 warn!(
39 "Retryable operation failed, attempt: {}, max_attempts: {}, backoff: {:?}, error: {:?}",
40 current_attempt, max_attempts, backoff, err
41 );
42 tokio::time::sleep(backoff).await;
43 backoff = std::cmp::min(backoff * 2, max_backoff);
44 }
45 }
46 }
47
48 panic!("retry loop should always return")
49}