Skip to content

Commit

Permalink
core: Change the RetryPolicy trait to allow waiting on arbitrary thin…
Browse files Browse the repository at this point in the history
…gs. (#1035)

* core: Change the RetryPolicy trait to allow waiting on arbitrary things.

Previously the only thing that that a retry would wait for was a period
of time, i.e. `Duration`. This adds another function to the `RetryPolicy` trait
that allows the implementer to wait on any condition they like. The
default implementation of the new method provides backward compatibility
by just sleeping for a period of time.

* Use async_trait.

* Include the Error since you may want to change the `wait` behavior based on the type of error encountered.

* Update doc comment to reflect new functionality.

* Change the argument ordering.

* Update sdk/core/src/policies/retry_policies/retry_policy.rs

Co-authored-by: Ryan Levick <[email protected]>

Co-authored-by: Ryan Levick <[email protected]>
  • Loading branch information
gorzell and rylev authored Aug 22, 2022
1 parent 3b8cb3a commit 4d058c7
Showing 1 changed file with 12 additions and 2 deletions.
14 changes: 12 additions & 2 deletions sdk/core/src/policies/retry_policies/retry_policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,33 @@ use crate::policies::{Policy, PolicyResult, Request};
use crate::sleep::sleep;
use crate::{Context, StatusCode};

use async_trait::async_trait;
use time::OffsetDateTime;

use std::sync::Arc;
use std::time::Duration;

/// A retry policy.
///
/// All retry policies follow a similar pattern only differing in how
/// In the simple form, the policies need only differ in how
/// they determine if the retry has expired and for how long they should
/// sleep between retries.
///
/// `wait` can be implemented in more complex cases where a simple test of time
/// is not enough.
#[async_trait]
pub trait RetryPolicy {
/// Determine if no more retries should be performed.
///
/// Must return true if no more retries should be attempted.
fn is_expired(&self, duration_since_start: Duration, retry_count: u32) -> bool;
/// Determine how long before the next retry should be attempted.
fn sleep_duration(&self, retry_count: u32) -> Duration;
/// A Future that will wait until the request can be retried.
/// `error` is the [`Error`] value the led to a retry attempt.
async fn wait(&self, _error: &Error, retry_count: u32) {
sleep(self.sleep_duration(retry_count)).await;
}
}

/// The status codes where a retry should be attempted.
Expand Down Expand Up @@ -116,7 +126,7 @@ where
}
retry_count += 1;

sleep(self.sleep_duration(retry_count)).await;
self.wait(&last_error, retry_count).await;
}
}
}

0 comments on commit 4d058c7

Please sign in to comment.