summaryrefslogtreecommitdiffhomepage
path: root/talpid-core
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2023-09-17 16:42:18 +0200
committerDavid Lönnhager <david.l@mullvad.net>2023-09-19 14:07:32 +0200
commitc8b9da33986f9d64b4c4e84324d2bb92fffc52f3 (patch)
treedd63d827c8d57a880ceecf88419a202a4b3d9f56 /talpid-core
parentae6a4a1d9fba88aa6b3a23f6fe1252bf474e99eb (diff)
downloadmullvadvpn-c8b9da33986f9d64b4c4e84324d2bb92fffc52f3.tar.xz
mullvadvpn-c8b9da33986f9d64b4c4e84324d2bb92fffc52f3.zip
Simplify immediate retry strategy
Diffstat (limited to 'talpid-core')
-rw-r--r--talpid-core/src/future_retry.rs56
1 files changed, 33 insertions, 23 deletions
diff --git a/talpid-core/src/future_retry.rs b/talpid-core/src/future_retry.rs
index f5dc7a8f72..f7b68a3f2d 100644
--- a/talpid-core/src/future_retry.rs
+++ b/talpid-core/src/future_retry.rs
@@ -2,23 +2,6 @@ use rand::{distributions::OpenClosed01, Rng};
use std::{future::Future, ops::Deref, time::Duration};
use talpid_time::sleep;
-/// Convenience function that works like [`retry_future`] but limits the number
-/// of retries to `max_retries`.
-pub async fn retry_future_n<
- F: FnMut() -> O + 'static,
- R: FnMut(&T) -> bool + 'static,
- D: Iterator<Item = Duration> + 'static,
- O: Future<Output = T>,
- T,
->(
- factory: F,
- should_retry: R,
- delays: D,
- max_retries: usize,
-) -> T {
- retry_future(factory, should_retry, delays.take(max_retries)).await
-}
-
/// Retries a future until it should stop as determined by the retry function, or when
/// the iterator returns `None`.
pub async fn retry_future<
@@ -44,9 +27,36 @@ pub async fn retry_future<
}
}
-/// Returns an iterator that repeats the same interval.
-pub fn constant_interval(interval: Duration) -> impl Iterator<Item = Duration> {
- std::iter::repeat(interval)
+/// Iterator that repeats the same interval, with an optional maximum no. of attempts.
+pub struct ConstantInterval {
+ interval: Duration,
+ attempt: usize,
+ max_attempts: Option<usize>,
+}
+
+impl ConstantInterval {
+ /// Creates a `ConstantInterval` that repeats `interval`, at most `max_attempts` times.
+ pub const fn new(interval: Duration, max_attempts: Option<usize>) -> ConstantInterval {
+ ConstantInterval {
+ interval,
+ attempt: 0,
+ max_attempts,
+ }
+ }
+}
+
+impl Iterator for ConstantInterval {
+ type Item = Duration;
+
+ fn next(&mut self) -> Option<Duration> {
+ if let Some(max_attempts) = self.max_attempts {
+ if self.attempt >= max_attempts {
+ return None;
+ }
+ }
+ self.attempt = self.attempt.saturating_add(1);
+ Some(self.interval)
+ }
}
/// Provides an exponential back-off timer to delay the next retry of a failed operation.
@@ -212,12 +222,12 @@ mod test {
let retry_interval_max = Duration::from_secs(24 * 60 * 60);
tokio::time::pause();
- let _ = retry_future_n(
+ let _ = retry_future(
|| async { 0 },
|_| true,
ExponentialBackoff::new(retry_interval_initial, retry_interval_factor)
- .max_delay(Some(retry_interval_max)),
- 5,
+ .max_delay(Some(retry_interval_max))
+ .take(5),
)
.await;
}