@@ -5,6 +5,9 @@ use std::time::Duration;
55
66/// A function that performs and retries the given operation according to a retry policy.
77///
8+ /// **Caution**: A retry policy without the number of attempts capped by [`MaxAttemptsRetryPolicy`]
9+ /// decorator will result in infinite retries.
10+ ///
811/// **Example**
912/// ```rust
1013/// # use std::time::Duration;
@@ -16,7 +19,8 @@ use std::time::Duration;
1619/// # Ok(42)
1720/// # }
1821/// #
19- /// let retry_policy = ExponentialBackoffRetryPolicy::new(Duration::from_millis(100));
22+ /// let retry_policy = ExponentialBackoffRetryPolicy::new(Duration::from_millis(100))
23+ /// .with_max_attempts(5);
2024///
2125/// let result = retry(operation, &retry_policy);
2226///```
@@ -57,6 +61,11 @@ pub trait RetryPolicy: Sized {
5761 ///
5862 /// If `None` is returned then no further retry attempt is made.
5963 fn next_delay ( & self , context : & RetryContext < Self :: E > ) -> Option < Duration > ;
64+
65+ /// Returns a new `RetryPolicy` that respects the given maximum attempts.
66+ fn with_max_attempts ( self , max_attempts : u32 ) -> MaxAttemptsRetryPolicy < Self > {
67+ MaxAttemptsRetryPolicy { inner_policy : self , max_attempts }
68+ }
6069}
6170
6271/// Represents the context of a retry operation.
@@ -103,3 +112,22 @@ impl<E: Error> RetryPolicy for ExponentialBackoffRetryPolicy<E> {
103112 Some ( delay)
104113 }
105114}
115+
116+ /// Decorates the given `RetryPolicy` to respect the given maximum attempts.
117+ pub struct MaxAttemptsRetryPolicy < T : RetryPolicy > {
118+ /// The underlying retry policy to use.
119+ inner_policy : T ,
120+ /// The maximum number of attempts to retry.
121+ max_attempts : u32 ,
122+ }
123+
124+ impl < T : RetryPolicy > RetryPolicy for MaxAttemptsRetryPolicy < T > {
125+ type E = T :: E ;
126+ fn next_delay ( & self , context : & RetryContext < Self :: E > ) -> Option < Duration > {
127+ if self . max_attempts == context. attempts_made {
128+ None
129+ } else {
130+ self . inner_policy . next_delay ( context)
131+ }
132+ }
133+ }
0 commit comments