sqs_lambda/
retry.rs

1use std::time::Duration;
2
3use futures_retry::{ErrorHandler, RetryPolicy};
4use rand::{Rng, SeedableRng};
5use rand_xorshift::XorShiftRng;
6use rusoto_core::RusotoError;
7
8pub struct RetryHandler {
9    attempt: u8,
10    max_attempts: u8,
11    rng: XorShiftRng,
12}
13
14impl RetryHandler {
15    pub fn new(attempts: u8) -> Self {
16        Self {
17            attempt: 0,
18            max_attempts: attempts,
19            rng: XorShiftRng::from_seed([0; 16]), // Unseeded
20        }
21    }
22}
23
24impl<E> ErrorHandler<RusotoError<E>> for RetryHandler {
25    type OutError = RusotoError<E>;
26
27    fn handle(&mut self, e: RusotoError<E>) -> RetryPolicy<RusotoError<E>> {
28        if self.attempt == self.max_attempts {
29            return RetryPolicy::ForwardError(e);
30        }
31        self.attempt += 1;
32        match e {
33            RusotoError::HttpDispatch(_) | RusotoError::Unknown(_) => {
34                let jitter: u64 = self.rng.gen_range(10, 50);
35                let backoff = jitter + (self.attempt as u64 * 10);
36                RetryPolicy::WaitRetry(Duration::from_millis(backoff))
37            }
38            _ => RetryPolicy::ForwardError(e),
39        }
40    }
41
42    fn ok(&mut self) {
43        self.attempt = 0;
44    }
45}