Skip to content

Commit

Permalink
Add max retries to Exponential Backoff retry policy (#421)
Browse files Browse the repository at this point in the history
  • Loading branch information
Valentin Mariette committed Jul 18, 2023
1 parent e30609f commit 0f7feb8
Showing 1 changed file with 37 additions and 10 deletions.
47 changes: 37 additions & 10 deletions graph-http/src/http_pipeline.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use async_trait::async_trait;
use backoff::backoff::Backoff;
use backoff::{future::retry, ExponentialBackoff, ExponentialBackoffBuilder};
use graph_error::{GraphFailure, GraphResult};
use http::StatusCode;
Expand Down Expand Up @@ -58,18 +59,22 @@ pub struct ExponentialBackoffRetryPolicy {
/// The maximum elapsed time after instantiating [`ExponentialBackoff`](struct.ExponentialBackoff.html) or calling
/// [`reset`](trait.Backoff.html#method.reset) after which [`next_backoff`](../trait.Backoff.html#method.reset) returns `None`.
pub max_elapsed_time: Option<Duration>,
pub max_retries: i32,
pub max_retries: usize,
}

impl ExponentialBackoffRetryPolicy {
pub(crate) fn get_retries_exponential_backoff(&self) -> ExponentialBackoff {
ExponentialBackoffBuilder::new()
.with_initial_interval(self.initial_interval)
.with_multiplier(self.multiplier)
.with_randomization_factor(self.randomization_factor)
.with_max_interval(self.max_interval)
.with_max_elapsed_time(self.max_elapsed_time)
.build()
pub(crate) fn get_exponential_backoff_with_max_retries(&self) -> ExponentialBackoffWithMaxRetries {
ExponentialBackoffWithMaxRetries {
exp: ExponentialBackoffBuilder::new()
.with_initial_interval(self.initial_interval)
.with_multiplier(self.multiplier)
.with_randomization_factor(self.randomization_factor)
.with_max_interval(self.max_interval)
.with_max_elapsed_time(self.max_elapsed_time)
.build(),
retries: 0,
max_retries: self.max_retries,
}
}
}

Expand All @@ -86,6 +91,28 @@ impl Default for ExponentialBackoffRetryPolicy {
}
}

pub struct ExponentialBackoffWithMaxRetries {
exp: ExponentialBackoff,
retries: usize,
max_retries: usize,
}

impl Backoff for ExponentialBackoffWithMaxRetries {
fn reset(&mut self) {
self.exp.reset();
self.retries = 0;
}

fn next_backoff(&mut self) -> Option<Duration> {
self.retries += 1;
if self.retries < self.max_retries + 1 {
self.exp.next_backoff()
} else {
None
}
}
}

#[async_trait]
impl HttpPipelinePolicy for ExponentialBackoffRetryPolicy {
async fn process_async(
Expand All @@ -94,7 +121,7 @@ impl HttpPipelinePolicy for ExponentialBackoffRetryPolicy {
request: &mut reqwest::Request,
pipeline: &[Arc<dyn HttpPipelinePolicy + Send + Sync>],
) -> GraphResult<reqwest::Response> {
retry(self.get_retries_exponential_backoff(), || async {
retry(self.get_exponential_backoff_with_max_retries(), || async {
Ok(pipeline[0]
.process_async(
client.clone(),
Expand Down

0 comments on commit 0f7feb8

Please sign in to comment.