From 8945c35655f7e0f6966d8314ab21a297181cc080 Mon Sep 17 00:00:00 2001 From: Ilya Titkov Date: Thu, 2 Dec 2021 21:03:54 +0300 Subject: [PATCH] Backoff policy stops if backoff iterator ends --- Cargo.toml | 2 +- src/policies/sequential.rs | 27 +++++++++++++++++++++------ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4385cc5..4bf5adb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fure" -version = "0.5.0" +version = "0.6.0" edition = "2021" authors = ["Ilya Titkov "] keywords = ["futures-retry", "retry", "futures"] diff --git a/src/policies/sequential.rs b/src/policies/sequential.rs index 88dc8ba..c550182 100644 --- a/src/policies/sequential.rs +++ b/src/policies/sequential.rs @@ -56,7 +56,7 @@ mod retry_backoff { /// Creates a policy to run futures sequentially with specified backoff. /// - /// Note: this policy has no stop condition, so for getting a result you should wrap it with [attempts](`super::super::attempts`), [cond](`super::super::cond`) or your own wrapper. + /// Note: this policy has no stop condition based on result, it retries while backoff iterator returns elements, so for getting the desired result you should wrap it with [attempts](`super::super::attempts`), [cond](`super::super::cond`) or your own wrapper. /// ## Example /// Sends at most 4 requests and returns the first [`Ok`] result. /// @@ -100,7 +100,7 @@ mod retry_backoff { } fn retry(mut self, _result: Option>) -> Option { - let delay = self.backoff.next().map(crate::sleep::sleep); + let delay = self.backoff.next().map(crate::sleep::sleep)?; Some(SeqDelay { backoff: Some(self.backoff), delay, @@ -114,7 +114,7 @@ mod retry_backoff { { backoff: Option, #[pin] - delay: Option, + delay: crate::sleep::Sleep, } } @@ -126,9 +126,9 @@ mod retry_backoff { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.project(); - match this.delay.as_pin_mut().map(|x| x.poll(cx)) { - Some(Poll::Pending) => Poll::Pending, - _ => Poll::Ready(backoff( + match this.delay.poll(cx) { + Poll::Pending => Poll::Pending, + Poll::Ready(_) => Poll::Ready(backoff( this.backoff.take().expect("SeqDelay Backoff must be some"), )), } @@ -172,6 +172,21 @@ mod tests { assert!(result.is_err()); }) } + + #[test] + fn should_stop_retrying_when_backoff_iter_exhausted() { + run_test(async { + let create_fut = || async { + crate::tests::yield_now().await; + Err::<(), ()>(()) + }; + + let policy = backoff(std::iter::empty()); + let result = retry(create_fut, policy).await; + + assert!(result.is_err()) + }) + } } mod attempts {