Unverified Commit 7ea3ed92 authored by Zelda Hessler's avatar Zelda Hessler Committed by GitHub
Browse files

No really, add the standard retry strategy to the orchestrator (#2741)

## Description
<!--- Describe your changes in detail -->
This PR adds support for the Standard retry strategy. The standard
strategy will be inserted into a service's config bag if a retry config
was set. Otherwise, unless another retry strategy was already set, a
`NeverRetryStrategy` will be set. This seemed like a reasonable default,
but I'm open to suggestions.

## Testing
<!--- Please describe in detail how you tested your changes -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
tests are included

---

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
parent 303d99b6
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ class ServiceRuntimePluginGenerator(
            "HttpConnector" to client.resolve("http_connector::HttpConnector"),
            "IdentityResolvers" to runtimeApi.resolve("client::identity::IdentityResolvers"),
            "InterceptorRegistrar" to runtimeApi.resolve("client::interceptors::InterceptorRegistrar"),
            "StandardRetryStrategy" to runtime.resolve("client::retries::strategy::StandardRetryStrategy"),
            "NeverRetryStrategy" to runtime.resolve("client::retries::strategy::NeverRetryStrategy"),
            "RetryClassifiers" to runtimeApi.resolve("client::retries::RetryClassifiers"),
            "Params" to endpointTypesGenerator.paramsStruct(),
@@ -141,11 +142,16 @@ class ServiceRuntimePluginGenerator(
                        #{retry_classifier_customizations};
                    cfg.set_retry_classifiers(retry_classifiers);

                    // TODO(enableNewSmithyRuntime): Wire up standard retry
                    cfg.set_retry_strategy(#{NeverRetryStrategy}::new());

                    let sleep_impl = self.handle.conf.sleep_impl();
                    let timeout_config = self.handle.conf.timeout_config();
                    let retry_config = self.handle.conf.retry_config();

                    if let Some(retry_config) = retry_config {
                        cfg.set_retry_strategy(#{StandardRetryStrategy}::new(retry_config));
                    } else if cfg.retry_strategy().is_none() {
                        cfg.set_retry_strategy(#{NeverRetryStrategy}::new());
                    }

                    let connector_settings = timeout_config.map(#{ConnectorSettings}::from_timeout_config).unwrap_or_default();
                    let connection: #{Box}<dyn #{Connection}> = #{Box}::new(#{DynConnectorAdapter}::new(
                        // TODO(enableNewSmithyRuntime): Replace the tower-based DynConnector and remove DynConnectorAdapter when deleting the middleware implementation
+3 −5
Original line number Diff line number Diff line
@@ -135,7 +135,7 @@ pub trait ConfigBagAccessors {
    fn retry_classifiers(&self) -> &RetryClassifiers;
    fn set_retry_classifiers(&mut self, retry_classifier: RetryClassifiers);

    fn retry_strategy(&self) -> &dyn RetryStrategy;
    fn retry_strategy(&self) -> Option<&dyn RetryStrategy>;
    fn set_retry_strategy(&mut self, retry_strategy: impl RetryStrategy + 'static);

    fn request_time(&self) -> Option<SharedTimeSource>;
@@ -255,10 +255,8 @@ impl ConfigBagAccessors for ConfigBag {
        self.put::<RetryClassifiers>(retry_classifiers);
    }

    fn retry_strategy(&self) -> &dyn RetryStrategy {
        &**self
            .get::<Box<dyn RetryStrategy>>()
            .expect("a retry strategy must be set")
    fn retry_strategy(&self) -> Option<&dyn RetryStrategy> {
        self.get::<Box<dyn RetryStrategy>>().map(|rs| &**rs)
    }

    fn set_retry_strategy(&mut self, retry_strategy: impl RetryStrategy + 'static) {
+2 −0
Original line number Diff line number Diff line
@@ -28,10 +28,12 @@ pin-project-lite = "0.2.7"
pin-utils = "0.1.0"
tokio = { version = "1.25", features = [] }
tracing = "0.1.37"
fastrand = "1.4"

[dev-dependencies]
aws-smithy-async = { path = "../aws-smithy-async", features = ["rt-tokio", "test-util"] }
aws-smithy-runtime-api = { path = "../aws-smithy-runtime-api", features = ["test-util"] }
aws-smithy-types = { path = "../aws-smithy-types", features = ["test-util"] }
tokio = { version = "1.25", features = ["macros", "rt", "test-util"] }
tracing-subscriber = { version = "0.3.15", features = ["env-filter"] }
tracing-test = "0.2.1"
+13 −2
Original line number Diff line number Diff line
@@ -132,7 +132,12 @@ async fn try_op(ctx: &mut InterceptorContext, cfg: &mut ConfigBag, interceptors:
    halt_on_err!([ctx] => interceptors.modify_before_retry_loop(ctx, cfg));

    let retry_strategy = cfg.retry_strategy();
    match retry_strategy.should_attempt_initial_request(cfg) {
    // If we got a retry strategy from the bag, ask it what to do.
    // Otherwise, assume we should attempt the initial request.
    let should_attempt = retry_strategy
        .map(|rs| rs.should_attempt_initial_request(cfg))
        .unwrap_or(Ok(ShouldAttempt::Yes));
    match should_attempt {
        // Yes, let's make a request
        Ok(ShouldAttempt::Yes) => trace!("retry strategy has OKed initial request"),
        // No, this request shouldn't be sent
@@ -178,7 +183,13 @@ async fn try_op(ctx: &mut InterceptorContext, cfg: &mut ConfigBag, interceptors:
        continue_on_err!([ctx] => maybe_timeout);

        let retry_strategy = cfg.retry_strategy();
        let should_attempt = halt_on_err!([ctx] => retry_strategy.should_attempt_retry(ctx, cfg));
        // If we got a retry strategy from the bag, ask it what to do.
        // If no strategy was set, we won't retry.
        let should_attempt = halt_on_err!(
            [ctx] => retry_strategy
                .map(|rs| rs.should_attempt_retry(ctx, cfg))
                .unwrap_or(Ok(ShouldAttempt::No)
        ));
        match should_attempt {
            // Yes, let's retry the request
            ShouldAttempt::Yes => continue,
+2 −0
Original line number Diff line number Diff line
@@ -6,7 +6,9 @@
#[cfg(feature = "test-util")]
mod fixed_delay;
mod never;
mod standard;

#[cfg(feature = "test-util")]
pub use fixed_delay::FixedDelayRetryStrategy;
pub use never::NeverRetryStrategy;
pub use standard::StandardRetryStrategy;
Loading