layer_climb_core/querier/middleware/
retry.rs

1use crate::prelude::*;
2use std::time::Duration;
3
4#[derive(Clone)]
5pub struct QueryRetryMiddleware {
6    pub max_attempts: u32,
7    pub backoff: Duration,
8}
9
10impl Default for QueryRetryMiddleware {
11    fn default() -> Self {
12        Self {
13            max_attempts: 3,
14            backoff: Duration::from_millis(100),
15        }
16    }
17}
18
19impl QueryRetryMiddleware {
20    pub async fn run<REQ: QueryRequest>(
21        &self,
22        req: REQ,
23        client: QueryClient,
24    ) -> Result<REQ::QueryResponse> {
25        let mut attempts = 0;
26        let mut backoff = self.backoff;
27
28        loop {
29            attempts += 1;
30            match req.request(client.clone()).await {
31                Ok(resp) => return Ok(resp),
32                Err(err) => {
33                    if attempts < self.max_attempts {
34                        futures_timer::Delay::new(backoff).await;
35                        backoff *= 2;
36                    } else {
37                        return Err(err);
38                    }
39                }
40            }
41        }
42    }
43}