@@ -20,7 +20,8 @@ use std::time::Duration;
2020/// # }
2121/// #
2222/// let retry_policy = ExponentialBackoffRetryPolicy::new(Duration::from_millis(100))
23- /// .with_max_attempts(5);
23+ /// .with_max_attempts(5)
24+ /// .with_max_total_delay(Duration::from_secs(2));
2425///
2526/// let result = retry(operation, &retry_policy);
2627///```
@@ -66,6 +67,11 @@ pub trait RetryPolicy: Sized {
6667 fn with_max_attempts ( self , max_attempts : u32 ) -> MaxAttemptsRetryPolicy < Self > {
6768 MaxAttemptsRetryPolicy { inner_policy : self , max_attempts }
6869 }
70+
71+ /// Returns a new `RetryPolicy` that respects the given total delay.
72+ fn with_max_total_delay ( self , max_total_delay : Duration ) -> MaxTotalDelayRetryPolicy < Self > {
73+ MaxTotalDelayRetryPolicy { inner_policy : self , max_total_delay }
74+ }
6975}
7076
7177/// Represents the context of a retry operation.
@@ -131,3 +137,24 @@ impl<T: RetryPolicy> RetryPolicy for MaxAttemptsRetryPolicy<T> {
131137 }
132138 }
133139}
140+
141+ /// Decorates the given `RetryPolicy` to respect the given maximum total delay.
142+ pub struct MaxTotalDelayRetryPolicy < T : RetryPolicy > {
143+ /// The underlying retry policy to use.
144+ inner_policy : T ,
145+ /// The maximum accumulated delay that will be allowed over all attempts.
146+ max_total_delay : Duration ,
147+ }
148+
149+ impl < T : RetryPolicy > RetryPolicy for MaxTotalDelayRetryPolicy < T > {
150+ type E = T :: E ;
151+ fn next_delay ( & self , context : & RetryContext < Self :: E > ) -> Option < Duration > {
152+ let next_delay = self . inner_policy . next_delay ( context) ;
153+ if let Some ( next_delay) = next_delay {
154+ if self . max_total_delay < context. accumulated_delay + next_delay {
155+ return None ;
156+ }
157+ }
158+ next_delay
159+ }
160+ }
0 commit comments