Unverified Commit 23d0f5ec authored by John DiSanti's avatar John DiSanti Committed by GitHub
Browse files

Implement timeouts in the orchestrator (#2661)

## Motivation and Context
This PR implements timeouts in the orchestrator.

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
parent bf23d57a
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ use aws_smithy_async::assert_elapsed;
use aws_smithy_async::rt::sleep::{AsyncSleep, Sleep};
use aws_smithy_client::never::NeverConnector;
use aws_smithy_http::result::SdkError;
use aws_smithy_types::error::display::DisplayErrorContext;
use aws_smithy_types::timeout::TimeoutConfig;
use std::fmt::Debug;
use std::sync::Arc;
@@ -117,7 +118,12 @@ async fn timeout_test(sleep_impl: Arc<dyn AsyncSleep>) -> Result<(), Box<dyn std
        .await
        .unwrap_err();

    assert_eq!("TimeoutError(TimeoutError { source: RequestTimeoutError { kind: \"operation timeout (all attempts including retries)\", duration: 500ms } })", format!("{:?}", err));
    let expected = "operation timeout (all attempts including retries) occurred after 500ms";
    let message = format!("{}", DisplayErrorContext(err));
    assert!(
        message.contains(expected),
        "expected '{message}' to contain '{expected}'"
    );
    // Assert 500ms have passed with a 150ms margin of error
    assert_elapsed!(now, Duration::from_millis(500), Duration::from_millis(150));

+6 −1
Original line number Diff line number Diff line
@@ -65,7 +65,12 @@ async fn test_timeout_service_ends_request_that_never_completes() {
        .await
        .unwrap_err();

    assert_eq!("TimeoutError(TimeoutError { source: RequestTimeoutError { kind: \"operation timeout (all attempts including retries)\", duration: 500ms } })", format!("{:?}", err));
    let expected = "operation timeout (all attempts including retries) occurred after 500ms";
    let message = format!("{}", DisplayErrorContext(err));
    assert!(
        message.contains(expected),
        "expected '{message}' to contain '{expected}'"
    );
    assert_elapsed!(now, std::time::Duration::from_secs_f32(0.5));
}

+21 −0
Original line number Diff line number Diff line
@@ -6,8 +6,12 @@
package software.amazon.smithy.rust.codegen.client.smithy.customizations

import software.amazon.smithy.rust.codegen.client.smithy.ClientRustModule
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginCustomization
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginSection
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
import software.amazon.smithy.rust.codegen.core.rustlang.rust
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.core.rustlang.writable
import software.amazon.smithy.rust.codegen.core.smithy.CodegenContext
@@ -260,3 +264,20 @@ class ResiliencyReExportCustomization(private val runtimeConfig: RuntimeConfig)
        }
    }
}

class ResiliencyServiceRuntimePluginCustomization : ServiceRuntimePluginCustomization() {
    override fun section(section: ServiceRuntimePluginSection): Writable = writable {
        if (section is ServiceRuntimePluginSection.AdditionalConfig) {
            rust(
                """
                if let Some(sleep_impl) = self.handle.conf.sleep_impl() {
                    ${section.configBagName}.put(sleep_impl);
                }
                if let Some(timeout_config) = self.handle.conf.timeout_config() {
                    ${section.configBagName}.put(timeout_config.clone());
                }
                """,
            )
        }
    }
}
+8 −0
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@ import software.amazon.smithy.rust.codegen.client.smithy.customizations.HttpVers
import software.amazon.smithy.rust.codegen.client.smithy.customizations.IdempotencyTokenGenerator
import software.amazon.smithy.rust.codegen.client.smithy.customizations.ResiliencyConfigCustomization
import software.amazon.smithy.rust.codegen.client.smithy.customizations.ResiliencyReExportCustomization
import software.amazon.smithy.rust.codegen.client.smithy.customizations.ResiliencyServiceRuntimePluginCustomization
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginCustomization
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
import software.amazon.smithy.rust.codegen.core.rustlang.Feature
import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
@@ -80,4 +82,10 @@ class RequiredCustomizations : ClientCodegenDecorator {
            }
        }
    }

    override fun serviceRuntimePluginCustomizations(
        codegenContext: ClientCodegenContext,
        baseCustomizations: List<ServiceRuntimePluginCustomization>,
    ): List<ServiceRuntimePluginCustomization> =
        baseCustomizations + listOf(ResiliencyServiceRuntimePluginCustomization())
}
+3 −2
Original line number Diff line number Diff line
@@ -37,12 +37,13 @@ macro_rules! assert_elapsed {
    ($start:expr, $dur:expr, $margin_of_error:expr) => {{
        let elapsed = $start.elapsed();
        // type ascription improves compiler error when wrong type is passed
        let lower: std::time::Duration = $dur;
        let margin_of_error: std::time::Duration = $margin_of_error;
        let lower: std::time::Duration = $dur - margin_of_error;
        let upper: std::time::Duration = $dur + margin_of_error;

        // Handles ms rounding
        assert!(
            elapsed >= lower && elapsed <= lower + margin_of_error,
            elapsed >= lower && elapsed <= upper,
            "actual = {:?}, expected = {:?}",
            elapsed,
            lower
Loading