diff --git a/CHANGELOG.next.toml b/CHANGELOG.next.toml index bcc8dcb0a4..c31d53f166 100644 --- a/CHANGELOG.next.toml +++ b/CHANGELOG.next.toml @@ -121,3 +121,15 @@ message = "The SDK has added support for timestreamwrite and timestreamquery. Su meta = { "breaking" = false, "tada" = true, "bug" = false } references = ["smithy-rs#2707", "aws-sdk-rust#114"] author = "rcoh" + +[[smithy-rs]] +message = "A newtype wrapper `SharedAsyncSleep` has been introduced and occurrences of `Arc` that appear in public APIs have been replaced with it." +references = ["smithy-rs#2742"] +meta = { "breaking" = true, "tada" = false, "bug" = false, "target" = "client" } +author = "ysaito1001" + +[[aws-sdk-rust]] +message = "A newtype wrapper `SharedAsyncSleep` has been introduced and occurrences of `Arc` that appear in public APIs have been replaced with it." +references = ["smithy-rs#2742"] +meta = { "breaking" = true, "tada" = false, "bug" = false } +author = "ysaito1001" diff --git a/aws/rust-runtime/aws-config/src/connector.rs b/aws/rust-runtime/aws-config/src/connector.rs index 634c7c7bfa..c924a072bf 100644 --- a/aws/rust-runtime/aws-config/src/connector.rs +++ b/aws/rust-runtime/aws-config/src/connector.rs @@ -19,11 +19,11 @@ pub use aws_smithy_client::conns::default_connector; #[cfg(all(feature = "native-tls", not(feature = "allow-compilation")))] compile_error!("Feature native-tls has been removed. For upgrade instructions, see: https://awslabs.github.io/smithy-rs/design/transport/connector.html"); -/// Given `ConnectorSettings` and an `AsyncSleep`, create a `DynConnector` from defaults depending on what cargo features are activated. +/// Given `ConnectorSettings` and a [`SharedAsyncSleep`](aws_smithy_async::rt::sleep::SharedAsyncSleep), create a `DynConnector` from defaults depending on what cargo features are activated. #[cfg(not(feature = "client-hyper"))] pub fn default_connector( _settings: &aws_smithy_client::http_connector::ConnectorSettings, - _sleep: Option>, + _sleep: Option, ) -> Option { None } diff --git a/aws/rust-runtime/aws-config/src/imds/client/token.rs b/aws/rust-runtime/aws-config/src/imds/client/token.rs index 213243a8cd..41e96777b4 100644 --- a/aws/rust-runtime/aws-config/src/imds/client/token.rs +++ b/aws/rust-runtime/aws-config/src/imds/client/token.rs @@ -18,7 +18,7 @@ use crate::imds::client::error::{ImdsError, TokenError, TokenErrorKind}; use crate::imds::client::ImdsResponseRetryClassifier; use aws_credential_types::cache::ExpiringCache; use aws_http::user_agent::UserAgentStage; -use aws_smithy_async::rt::sleep::AsyncSleep; +use aws_smithy_async::rt::sleep::SharedAsyncSleep; use aws_smithy_async::time::SharedTimeSource; use aws_smithy_client::erase::DynConnector; use aws_smithy_client::retry; @@ -84,7 +84,7 @@ impl TokenMiddleware { token_ttl: Duration, retry_config: retry::Config, timeout_config: TimeoutConfig, - sleep_impl: Option>, + sleep_impl: Option, ) -> Self { let mut inner_builder = aws_smithy_client::Client::builder() .connector(connector) diff --git a/aws/rust-runtime/aws-config/src/lib.rs b/aws/rust-runtime/aws-config/src/lib.rs index 5364d1bcb5..5871762204 100644 --- a/aws/rust-runtime/aws-config/src/lib.rs +++ b/aws/rust-runtime/aws-config/src/lib.rs @@ -154,7 +154,7 @@ mod loader { use aws_credential_types::cache::CredentialsCache; use aws_credential_types::provider::{ProvideCredentials, SharedCredentialsProvider}; - use aws_smithy_async::rt::sleep::{default_async_sleep, AsyncSleep}; + use aws_smithy_async::rt::sleep::{default_async_sleep, AsyncSleep, SharedAsyncSleep}; use aws_smithy_async::time::{SharedTimeSource, TimeSource}; use aws_smithy_client::http_connector::HttpConnector; use aws_smithy_types::retry::RetryConfig; @@ -185,7 +185,7 @@ mod loader { endpoint_url: Option, region: Option>, retry_config: Option, - sleep: Option>, + sleep: Option, timeout_config: Option, provider_config: Option, http_connector: Option, @@ -260,7 +260,7 @@ mod loader { /// is used to create timeout futures. pub fn sleep_impl(mut self, sleep: impl AsyncSleep + 'static) -> Self { // it's possible that we could wrapping an `Arc in an `Arc` and that's OK - self.sleep = Some(Arc::new(sleep)); + self.sleep = Some(SharedAsyncSleep::new(sleep)); self } diff --git a/aws/rust-runtime/aws-config/src/provider_config.rs b/aws/rust-runtime/aws-config/src/provider_config.rs index 7d596b2c2e..afa2989811 100644 --- a/aws/rust-runtime/aws-config/src/provider_config.rs +++ b/aws/rust-runtime/aws-config/src/provider_config.rs @@ -6,7 +6,7 @@ //! Configuration Options for Credential Providers use aws_credential_types::time_source::TimeSource; -use aws_smithy_async::rt::sleep::{default_async_sleep, AsyncSleep}; +use aws_smithy_async::rt::sleep::{default_async_sleep, AsyncSleep, SharedAsyncSleep}; use aws_smithy_async::time::SharedTimeSource; use aws_smithy_client::erase::DynConnector; use aws_smithy_types::error::display::DisplayErrorContext; @@ -41,7 +41,7 @@ pub struct ProviderConfig { fs: Fs, time_source: SharedTimeSource, connector: HttpConnector, - sleep: Option>, + sleep: Option, region: Option, /// An AWS profile created from `ProfileFiles` and a `profile_name` parsed_profile: Arc>>, @@ -65,7 +65,7 @@ impl Debug for ProviderConfig { impl Default for ProviderConfig { fn default() -> Self { let connector = HttpConnector::ConnectorFn(Arc::new( - |settings: &ConnectorSettings, sleep: Option>| { + |settings: &ConnectorSettings, sleep: Option| { default_connector(settings, sleep) }, )); @@ -195,7 +195,7 @@ impl ProviderConfig { } #[allow(dead_code)] - pub(crate) fn sleep(&self) -> Option> { + pub(crate) fn sleep(&self) -> Option { self.sleep.clone() } @@ -332,8 +332,7 @@ impl ProviderConfig { C::Future: Unpin + Send + 'static, C::Error: Into>, { - let connector_fn = move |settings: &ConnectorSettings, - sleep: Option>| { + let connector_fn = move |settings: &ConnectorSettings, sleep: Option| { let mut builder = aws_smithy_client::hyper_ext::Adapter::builder() .connector_settings(settings.clone()); if let Some(sleep) = sleep { @@ -350,7 +349,7 @@ impl ProviderConfig { /// Override the sleep implementation for this configuration pub fn with_sleep(self, sleep: impl AsyncSleep + 'static) -> Self { ProviderConfig { - sleep: Some(Arc::new(sleep)), + sleep: Some(SharedAsyncSleep::new(sleep)), ..self } } diff --git a/aws/rust-runtime/aws-credential-types/external-types.toml b/aws/rust-runtime/aws-credential-types/external-types.toml index 83527f561e..20337b394d 100644 --- a/aws/rust-runtime/aws-credential-types/external-types.toml +++ b/aws/rust-runtime/aws-credential-types/external-types.toml @@ -1,3 +1,3 @@ allowed_external_types = [ - "aws_smithy_async::rt::sleep::AsyncSleep", + "aws_smithy_async::rt::sleep::SharedAsyncSleep", ] diff --git a/aws/rust-runtime/aws-credential-types/src/cache/lazy_caching.rs b/aws/rust-runtime/aws-credential-types/src/cache/lazy_caching.rs index 1081b8f336..ae1a6e2d36 100644 --- a/aws/rust-runtime/aws-credential-types/src/cache/lazy_caching.rs +++ b/aws/rust-runtime/aws-credential-types/src/cache/lazy_caching.rs @@ -5,11 +5,10 @@ //! Lazy, credentials cache implementation -use std::sync::Arc; use std::time::{Duration, Instant}; use aws_smithy_async::future::timeout::Timeout; -use aws_smithy_async::rt::sleep::AsyncSleep; +use aws_smithy_async::rt::sleep::{AsyncSleep, SharedAsyncSleep}; use tracing::{debug, info, info_span, Instrument}; use crate::cache::{ExpiringCache, ProvideCachedCredentials}; @@ -25,7 +24,7 @@ const DEFAULT_BUFFER_TIME_JITTER_FRACTION: fn() -> f64 = fastrand::f64; #[derive(Debug)] pub(crate) struct LazyCredentialsCache { time: TimeSource, - sleeper: Arc, + sleeper: SharedAsyncSleep, cache: ExpiringCache, provider: SharedCredentialsProvider, load_timeout: Duration, @@ -37,7 +36,7 @@ pub(crate) struct LazyCredentialsCache { impl LazyCredentialsCache { fn new( time: TimeSource, - sleeper: Arc, + sleeper: SharedAsyncSleep, provider: SharedCredentialsProvider, load_timeout: Duration, buffer_time: Duration, @@ -133,12 +132,11 @@ use crate::Credentials; pub use builder::Builder; mod builder { - use std::sync::Arc; use std::time::Duration; use crate::cache::{CredentialsCache, Inner}; use crate::provider::SharedCredentialsProvider; - use aws_smithy_async::rt::sleep::{default_async_sleep, AsyncSleep}; + use aws_smithy_async::rt::sleep::{default_async_sleep, SharedAsyncSleep}; use super::TimeSource; use super::{ @@ -160,7 +158,7 @@ mod builder { /// `build` to create a `LazyCredentialsCache`. #[derive(Clone, Debug, Default)] pub struct Builder { - sleep: Option>, + sleep: Option, time_source: Option, load_timeout: Option, buffer_time: Option, @@ -174,22 +172,22 @@ mod builder { Default::default() } - /// Implementation of [`AsyncSleep`] to use for timeouts. + /// Implementation of [`AsyncSleep`](aws_smithy_async::rt::sleep::AsyncSleep) to use for timeouts. /// /// This enables use of the `LazyCredentialsCache` with other async runtimes. /// If using Tokio as the async runtime, this should be set to an instance of /// [`TokioSleep`](aws_smithy_async::rt::sleep::TokioSleep). - pub fn sleep(mut self, sleep: Arc) -> Self { + pub fn sleep(mut self, sleep: SharedAsyncSleep) -> Self { self.set_sleep(Some(sleep)); self } - /// Implementation of [`AsyncSleep`] to use for timeouts. + /// Implementation of [`AsyncSleep`](aws_smithy_async::rt::sleep::AsyncSleep) to use for timeouts. /// /// This enables use of the `LazyCredentialsCache` with other async runtimes. /// If using Tokio as the async runtime, this should be set to an instance of /// [`TokioSleep`](aws_smithy_async::rt::sleep::TokioSleep). - pub fn set_sleep(&mut self, sleep: Option>) -> &mut Self { + pub fn set_sleep(&mut self, sleep: Option) -> &mut Self { self.sleep = sleep; self } @@ -347,7 +345,7 @@ mod tests { use std::sync::{Arc, Mutex}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; - use aws_smithy_async::rt::sleep::TokioSleep; + use aws_smithy_async::rt::sleep::{SharedAsyncSleep, TokioSleep}; use tracing::info; use tracing_test::traced_test; @@ -372,7 +370,7 @@ mod tests { let load_list = Arc::new(Mutex::new(load_list)); LazyCredentialsCache::new( time, - Arc::new(TokioSleep::new()), + SharedAsyncSleep::new(TokioSleep::new()), SharedCredentialsProvider::new(provide_credentials_fn(move || { let list = load_list.clone(); async move { @@ -414,7 +412,7 @@ mod tests { })); let credentials_cache = LazyCredentialsCache::new( TimeSource::testing(&time), - Arc::new(TokioSleep::new()), + SharedAsyncSleep::new(TokioSleep::new()), provider, DEFAULT_LOAD_TIMEOUT, DEFAULT_BUFFER_TIME, @@ -534,7 +532,7 @@ mod tests { let time = TestingTimeSource::new(epoch_secs(100)); let credentials_cache = LazyCredentialsCache::new( TimeSource::testing(&time), - Arc::new(TokioSleep::new()), + SharedAsyncSleep::new(TokioSleep::new()), SharedCredentialsProvider::new(provide_credentials_fn(|| async { aws_smithy_async::future::never::Never::new().await; Ok(credentials(1000)) diff --git a/aws/rust-runtime/aws-inlineable/src/endpoint_discovery.rs b/aws/rust-runtime/aws-inlineable/src/endpoint_discovery.rs index e74ceddb00..d4ffc7d116 100644 --- a/aws/rust-runtime/aws-inlineable/src/endpoint_discovery.rs +++ b/aws/rust-runtime/aws-inlineable/src/endpoint_discovery.rs @@ -5,8 +5,8 @@ //! Maintain a cache of discovered endpoints -use aws_smithy_async::rt::sleep::AsyncSleep; -use aws_smithy_async::time::TimeSource; +use aws_smithy_async::rt::sleep::{AsyncSleep, SharedAsyncSleep}; +use aws_smithy_async::time::SharedTimeSource; use aws_smithy_client::erase::boxclone::BoxFuture; use aws_smithy_http::endpoint::{ResolveEndpoint, ResolveEndpointError}; use aws_smithy_types::endpoint::Endpoint; @@ -24,8 +24,8 @@ pub struct ReloadEndpoint { endpoint: Arc>>, error: Arc>>, rx: Receiver<()>, - sleep: Arc, - time: Arc, + sleep: SharedAsyncSleep, + time: SharedTimeSource, } impl Debug for ReloadEndpoint { @@ -106,8 +106,8 @@ impl ExpiringEndpoint { pub(crate) async fn create_cache( loader_fn: impl Fn() -> F + Send + Sync + 'static, - sleep: Arc, - time: Arc, + sleep: SharedAsyncSleep, + time: SharedTimeSource, ) -> Result<(EndpointCache, ReloadEndpoint), ResolveEndpointError> where F: Future> + Send + 'static, @@ -155,9 +155,9 @@ impl EndpointCache { #[cfg(test)] mod test { use crate::endpoint_discovery::create_cache; - use aws_smithy_async::rt::sleep::TokioSleep; + use aws_smithy_async::rt::sleep::{SharedAsyncSleep, TokioSleep}; use aws_smithy_async::test_util::controlled_time_and_sleep; - use aws_smithy_async::time::SystemTimeSource; + use aws_smithy_async::time::{SharedTimeSource, SystemTimeSource}; use aws_smithy_types::endpoint::Endpoint; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; @@ -178,8 +178,8 @@ mod test { SystemTime::now(), )) }, - Arc::new(TokioSleep::new()), - Arc::new(SystemTimeSource::new()), + SharedAsyncSleep::new(TokioSleep::new()), + SharedTimeSource::new(SystemTimeSource::new()), ) .await .unwrap(); @@ -204,8 +204,8 @@ mod test { )) } }, - Arc::new(TokioSleep::new()), - Arc::new(SystemTimeSource::new()), + SharedAsyncSleep::new(TokioSleep::new()), + SharedTimeSource::new(SystemTimeSource::new()), ) .await .expect("returns an endpoint"); @@ -248,8 +248,8 @@ mod test { )) } }, - Arc::new(sleep.clone()), - Arc::new(time.clone()), + SharedAsyncSleep::new(sleep.clone()), + SharedTimeSource::new(time.clone()), ) .await .expect("first load success"); diff --git a/aws/rust-runtime/aws-types/external-types.toml b/aws/rust-runtime/aws-types/external-types.toml index 6c1d2b5aab..830795ad27 100644 --- a/aws/rust-runtime/aws-types/external-types.toml +++ b/aws/rust-runtime/aws-types/external-types.toml @@ -1,7 +1,7 @@ allowed_external_types = [ "aws_credential_types::cache::CredentialsCache", "aws_credential_types::provider::SharedCredentialsProvider", - "aws_smithy_async::rt::sleep::AsyncSleep", + "aws_smithy_async::rt::sleep::SharedAsyncSleep", "aws_smithy_async::time::TimeSource", "aws_smithy_async::time::SharedTimeSource", "aws_smithy_client::http_connector", diff --git a/aws/rust-runtime/aws-types/src/sdk_config.rs b/aws/rust-runtime/aws-types/src/sdk_config.rs index af60e88f5d..4d0728a985 100644 --- a/aws/rust-runtime/aws-types/src/sdk_config.rs +++ b/aws/rust-runtime/aws-types/src/sdk_config.rs @@ -9,11 +9,9 @@ //! //! This module contains an shared configuration representation that is agnostic from a specific service. -use std::sync::Arc; - use aws_credential_types::cache::CredentialsCache; use aws_credential_types::provider::SharedCredentialsProvider; -use aws_smithy_async::rt::sleep::AsyncSleep; +use aws_smithy_async::rt::sleep::SharedAsyncSleep; use aws_smithy_async::time::{SharedTimeSource, TimeSource}; use aws_smithy_client::http_connector::HttpConnector; use aws_smithy_types::retry::RetryConfig; @@ -55,7 +53,7 @@ pub struct SdkConfig { region: Option, endpoint_url: Option, retry_config: Option, - sleep_impl: Option>, + sleep_impl: Option, time_source: Option, timeout_config: Option, http_connector: Option, @@ -76,7 +74,7 @@ pub struct Builder { region: Option, endpoint_url: Option, retry_config: Option, - sleep_impl: Option>, + sleep_impl: Option, time_source: Option, timeout_config: Option, http_connector: Option, @@ -241,8 +239,7 @@ impl Builder { /// # Examples /// /// ```rust - /// use std::sync::Arc; - /// use aws_smithy_async::rt::sleep::{AsyncSleep, Sleep}; + /// use aws_smithy_async::rt::sleep::{AsyncSleep, SharedAsyncSleep, Sleep}; /// use aws_types::SdkConfig; /// /// ##[derive(Debug)] @@ -254,10 +251,10 @@ impl Builder { /// } /// } /// - /// let sleep_impl = Arc::new(ForeverSleep); + /// let sleep_impl = SharedAsyncSleep::new(ForeverSleep); /// let config = SdkConfig::builder().sleep_impl(sleep_impl).build(); /// ``` - pub fn sleep_impl(mut self, sleep_impl: Arc) -> Self { + pub fn sleep_impl(mut self, sleep_impl: SharedAsyncSleep) -> Self { self.set_sleep_impl(Some(sleep_impl)); self } @@ -270,7 +267,7 @@ impl Builder { /// /// # Examples /// ```rust - /// # use aws_smithy_async::rt::sleep::{AsyncSleep, Sleep}; + /// # use aws_smithy_async::rt::sleep::{AsyncSleep, SharedAsyncSleep, Sleep}; /// # use aws_types::sdk_config::{Builder, SdkConfig}; /// #[derive(Debug)] /// pub struct ForeverSleep; @@ -282,7 +279,7 @@ impl Builder { /// } /// /// fn set_never_ending_sleep_impl(builder: &mut Builder) { - /// let sleep_impl = std::sync::Arc::new(ForeverSleep); + /// let sleep_impl = SharedAsyncSleep::new(ForeverSleep); /// builder.set_sleep_impl(Some(sleep_impl)); /// } /// @@ -290,7 +287,7 @@ impl Builder { /// set_never_ending_sleep_impl(&mut builder); /// let config = builder.build(); /// ``` - pub fn set_sleep_impl(&mut self, sleep_impl: Option>) -> &mut Self { + pub fn set_sleep_impl(&mut self, sleep_impl: Option) -> &mut Self { self.sleep_impl = sleep_impl; self } @@ -558,7 +555,7 @@ impl SdkConfig { #[doc(hidden)] /// Configured sleep implementation - pub fn sleep_impl(&self) -> Option> { + pub fn sleep_impl(&self) -> Option { self.sleep_impl.clone() } @@ -568,13 +565,13 @@ impl SdkConfig { } /// Configured credentials provider - pub fn credentials_provider(&self) -> Option<&SharedCredentialsProvider> { - self.credentials_provider.as_ref() + pub fn credentials_provider(&self) -> Option { + self.credentials_provider.clone() } /// Configured time source - pub fn time_source(&self) -> Option<&SharedTimeSource> { - self.time_source.as_ref() + pub fn time_source(&self) -> Option { + self.time_source.clone() } /// Configured app name diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/CredentialProviders.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/CredentialProviders.kt index eb03212135..6bc42cdbc2 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/CredentialProviders.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/CredentialProviders.kt @@ -46,7 +46,7 @@ class CredentialsProviderDecorator : ClientCodegenDecorator { override fun extraSections(codegenContext: ClientCodegenContext): List = listOf( adhocCustomization { section -> - rust("${section.serviceConfigBuilder}.set_credentials_provider(${section.sdkConfig}.credentials_provider().cloned());") + rust("${section.serviceConfigBuilder}.set_credentials_provider(${section.sdkConfig}.credentials_provider());") }, ) diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/SdkConfigDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/SdkConfigDecorator.kt index b77b5c9bc7..20457237c9 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/SdkConfigDecorator.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/SdkConfigDecorator.kt @@ -77,7 +77,7 @@ class GenericSmithySdkConfigSettings : ClientCodegenDecorator { ${section.serviceConfigBuilder}.set_sleep_impl(${section.sdkConfig}.sleep_impl()); ${section.serviceConfigBuilder}.set_http_connector(${section.sdkConfig}.http_connector().cloned()); - ${section.serviceConfigBuilder}.set_time_source(${section.sdkConfig}.time_source().cloned()); + ${section.serviceConfigBuilder}.set_time_source(${section.sdkConfig}.time_source()); """, ) }, diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/timestream/TimestreamDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/timestream/TimestreamDecorator.kt index 8b8bffe398..ac2e8928e0 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/timestream/TimestreamDecorator.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/timestream/TimestreamDecorator.kt @@ -77,7 +77,7 @@ class TimestreamDecorator : ClientCodegenDecorator { pub async fn enable_endpoint_discovery(self) -> #{Result}<(Self, #{endpoint_discovery}::ReloadEndpoint), #{ResolveEndpointError}> { let mut new_conf = self.conf().clone(); let sleep = self.conf().sleep_impl().expect("sleep impl must be provided"); - let time = ::std::sync::Arc::new(self.conf().time_source.clone()); + let time = self.conf().time_source.clone(); let (resolver, reloader) = #{endpoint_discovery}::create_cache( move || { let client = self.clone(); diff --git a/aws/sdk/integration-tests/dynamodb/tests/timeouts.rs b/aws/sdk/integration-tests/dynamodb/tests/timeouts.rs index b566c598c7..d1a9b9369e 100644 --- a/aws/sdk/integration-tests/dynamodb/tests/timeouts.rs +++ b/aws/sdk/integration-tests/dynamodb/tests/timeouts.rs @@ -3,13 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -use std::sync::Arc; use std::time::Duration; use aws_credential_types::provider::SharedCredentialsProvider; use aws_credential_types::Credentials; use aws_sdk_dynamodb::error::SdkError; -use aws_smithy_async::rt::sleep::{AsyncSleep, Sleep}; +use aws_smithy_async::rt::sleep::{AsyncSleep, SharedAsyncSleep, Sleep}; use aws_smithy_client::never::NeverConnector; use aws_smithy_types::retry::RetryConfig; use aws_smithy_types::timeout::TimeoutConfig; @@ -37,7 +36,7 @@ async fn api_call_timeout_retries() { .build(), ) .retry_config(RetryConfig::standard()) - .sleep_impl(Arc::new(InstantSleep)) + .sleep_impl(SharedAsyncSleep::new(InstantSleep)) .build(); let client = aws_sdk_dynamodb::Client::from_conf(aws_sdk_dynamodb::Config::new(&conf)); let resp = client @@ -70,7 +69,7 @@ async fn no_retries_on_operation_timeout() { .build(), ) .retry_config(RetryConfig::standard()) - .sleep_impl(Arc::new(InstantSleep)) + .sleep_impl(SharedAsyncSleep::new(InstantSleep)) .build(); let client = aws_sdk_dynamodb::Client::from_conf(aws_sdk_dynamodb::Config::new(&conf)); let resp = client diff --git a/aws/sdk/integration-tests/no-default-features/tests/client-construction.rs b/aws/sdk/integration-tests/no-default-features/tests/client-construction.rs index 64f0137b24..0ee5c7a5c3 100644 --- a/aws/sdk/integration-tests/no-default-features/tests/client-construction.rs +++ b/aws/sdk/integration-tests/no-default-features/tests/client-construction.rs @@ -27,7 +27,9 @@ async fn test_clients_from_service_config() { } let config = aws_sdk_s3::Config::builder() - .sleep_impl(std::sync::Arc::new(StubSleep {})) + .sleep_impl(aws_smithy_async::rt::sleep::SharedAsyncSleep::new( + StubSleep {}, + )) .build(); // This will panic due to the lack of an HTTP connector aws_sdk_s3::Client::from_conf(config); diff --git a/aws/sdk/integration-tests/s3/tests/alternative-async-runtime.rs b/aws/sdk/integration-tests/s3/tests/alternative-async-runtime.rs index 7d6e84a90f..db36cfeb92 100644 --- a/aws/sdk/integration-tests/s3/tests/alternative-async-runtime.rs +++ b/aws/sdk/integration-tests/s3/tests/alternative-async-runtime.rs @@ -12,13 +12,12 @@ use aws_sdk_s3::types::{ }; use aws_sdk_s3::{Client, Config}; use aws_smithy_async::assert_elapsed; -use aws_smithy_async::rt::sleep::{AsyncSleep, Sleep}; +use aws_smithy_async::rt::sleep::{AsyncSleep, SharedAsyncSleep, 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; use std::time::{Duration, Instant}; #[derive(Debug)] @@ -34,7 +33,8 @@ impl AsyncSleep for SmolSleep { #[test] fn test_smol_runtime_timeouts() { - if let Err(err) = smol::block_on(async { timeout_test(Arc::new(SmolSleep)).await }) { + if let Err(err) = smol::block_on(async { timeout_test(SharedAsyncSleep::new(SmolSleep)).await }) + { println!("{err}"); panic!(); } @@ -42,7 +42,7 @@ fn test_smol_runtime_timeouts() { #[test] fn test_smol_runtime_retry() { - if let Err(err) = smol::block_on(async { retry_test(Arc::new(SmolSleep)).await }) { + if let Err(err) = smol::block_on(async { retry_test(SharedAsyncSleep::new(SmolSleep)).await }) { println!("{err}"); panic!(); } @@ -59,9 +59,9 @@ impl AsyncSleep for AsyncStdSleep { #[test] fn test_async_std_runtime_timeouts() { - if let Err(err) = - async_std::task::block_on(async { timeout_test(Arc::new(AsyncStdSleep)).await }) - { + if let Err(err) = async_std::task::block_on(async { + timeout_test(SharedAsyncSleep::new(AsyncStdSleep)).await + }) { println!("{err}"); panic!(); } @@ -69,14 +69,15 @@ fn test_async_std_runtime_timeouts() { #[test] fn test_async_std_runtime_retry() { - if let Err(err) = async_std::task::block_on(async { retry_test(Arc::new(AsyncStdSleep)).await }) + if let Err(err) = + async_std::task::block_on(async { retry_test(SharedAsyncSleep::new(AsyncStdSleep)).await }) { println!("{err}"); panic!(); } } -async fn timeout_test(sleep_impl: Arc) -> Result<(), Box> { +async fn timeout_test(sleep_impl: SharedAsyncSleep) -> Result<(), Box> { let conn = NeverConnector::new(); let region = Region::from_static("us-east-2"); let timeout_config = TimeoutConfig::builder() @@ -130,7 +131,7 @@ async fn timeout_test(sleep_impl: Arc) -> Result<(), Box) -> Result<(), Box> { +async fn retry_test(sleep_impl: SharedAsyncSleep) -> Result<(), Box> { let conn = NeverConnector::new(); let conf = aws_types::SdkConfig::builder() .region(Region::new("us-east-2")) diff --git a/aws/sdk/integration-tests/s3/tests/make-connector-override.rs b/aws/sdk/integration-tests/s3/tests/make-connector-override.rs index fc816b8188..90eb79d70c 100644 --- a/aws/sdk/integration-tests/s3/tests/make-connector-override.rs +++ b/aws/sdk/integration-tests/s3/tests/make-connector-override.rs @@ -5,7 +5,7 @@ use aws_credential_types::provider::SharedCredentialsProvider; use aws_credential_types::Credentials; -use aws_smithy_async::rt::sleep::{AsyncSleep, TokioSleep}; +use aws_smithy_async::rt::sleep::{SharedAsyncSleep, TokioSleep}; use aws_smithy_client::http_connector::{ConnectorSettings, HttpConnector}; use aws_smithy_client::test_connection; @@ -25,7 +25,7 @@ async fn make_connector_fn_test() { let sentinel = Arc::new(AtomicUsize::new(0)); let connector_sentinel = sentinel.clone(); let connector_with_counter = HttpConnector::ConnectorFn(Arc::new( - move |_settings: &ConnectorSettings, _sleep: Option>| { + move |_settings: &ConnectorSettings, _sleep: Option| { connector_sentinel.fetch_add(1, Ordering::Relaxed); Some(test_connection::infallible_connection_fn(|_req| { http::Response::builder().status(200).body("ok!").unwrap() @@ -60,7 +60,7 @@ async fn timeouts_can_be_set_by_service() { let sdk_config = SdkConfig::builder() .credentials_provider(SharedCredentialsProvider::new(Credentials::for_tests())) .region(Region::from_static("us-east-1")) - .sleep_impl(Arc::new(TokioSleep::new())) + .sleep_impl(SharedAsyncSleep::new(TokioSleep::new())) .timeout_config( TimeoutConfig::builder() .operation_timeout(Duration::from_secs(5)) diff --git a/aws/sdk/integration-tests/s3/tests/reconnects.rs b/aws/sdk/integration-tests/s3/tests/reconnects.rs index 85afcd40a9..91935319fb 100644 --- a/aws/sdk/integration-tests/s3/tests/reconnects.rs +++ b/aws/sdk/integration-tests/s3/tests/reconnects.rs @@ -5,7 +5,7 @@ use aws_credential_types::provider::SharedCredentialsProvider; use aws_credential_types::Credentials; -use aws_smithy_async::rt::sleep::TokioSleep; +use aws_smithy_async::rt::sleep::{SharedAsyncSleep, TokioSleep}; use aws_smithy_client::test_connection::wire_mock::{ check_matches, ReplayedEvent, WireLevelTestConnection, }; @@ -13,7 +13,6 @@ use aws_smithy_client::{ev, match_events}; use aws_smithy_types::retry::{ReconnectMode, RetryConfig}; use aws_types::region::Region; use aws_types::SdkConfig; -use std::sync::Arc; #[tokio::test] /// test that disabling reconnects on retry config disables them for the client @@ -28,7 +27,7 @@ async fn disable_reconnects() { let sdk_config = SdkConfig::builder() .region(Region::from_static("us-east-2")) .credentials_provider(SharedCredentialsProvider::new(Credentials::for_tests())) - .sleep_impl(Arc::new(TokioSleep::new())) + .sleep_impl(SharedAsyncSleep::new(TokioSleep::new())) .endpoint_url(mock.endpoint_url()) .http_connector(mock.http_connector()) .retry_config( @@ -68,7 +67,7 @@ async fn reconnect_on_503() { let sdk_config = SdkConfig::builder() .region(Region::from_static("us-east-2")) .credentials_provider(SharedCredentialsProvider::new(Credentials::for_tests())) - .sleep_impl(Arc::new(TokioSleep::new())) + .sleep_impl(SharedAsyncSleep::new(TokioSleep::new())) .endpoint_url(mock.endpoint_url()) .http_connector(mock.http_connector()) .retry_config(RetryConfig::standard()) diff --git a/aws/sdk/integration-tests/s3/tests/sleep_impl_use_cases.rs b/aws/sdk/integration-tests/s3/tests/sleep_impl_use_cases.rs index 182214e477..dfa82e9660 100644 --- a/aws/sdk/integration-tests/s3/tests/sleep_impl_use_cases.rs +++ b/aws/sdk/integration-tests/s3/tests/sleep_impl_use_cases.rs @@ -8,7 +8,7 @@ mod with_sdk_config { use aws_config::timeout::TimeoutConfig; use aws_config::SdkConfig; use aws_sdk_s3 as s3; - use std::sync::Arc; + use aws_smithy_async::rt::sleep::SharedAsyncSleep; use std::time::Duration; #[tokio::test] @@ -101,7 +101,9 @@ mod with_sdk_config { .build(), ) .retry_config(RetryConfig::standard().with_max_attempts(2)) - .sleep_impl(Arc::new(aws_smithy_async::rt::sleep::TokioSleep::new())) + .sleep_impl(SharedAsyncSleep::new( + aws_smithy_async::rt::sleep::TokioSleep::new(), + )) .build(); assert!(config.timeout_config().unwrap().has_timeouts()); assert!(config.retry_config().unwrap().has_retry()); @@ -114,7 +116,7 @@ mod with_service_config { use aws_config::timeout::TimeoutConfig; use aws_config::SdkConfig; use aws_sdk_s3 as s3; - use std::sync::Arc; + use aws_smithy_async::rt::sleep::SharedAsyncSleep; use std::time::Duration; #[test] @@ -188,7 +190,9 @@ mod with_service_config { .build(), ) .retry_config(RetryConfig::standard().with_max_attempts(2)) - .sleep_impl(Arc::new(aws_smithy_async::rt::sleep::TokioSleep::new())) + .sleep_impl(SharedAsyncSleep::new( + aws_smithy_async::rt::sleep::TokioSleep::new(), + )) .build(); let _s3 = s3::Client::new(&config); } diff --git a/aws/sdk/integration-tests/s3/tests/timeouts.rs b/aws/sdk/integration-tests/s3/tests/timeouts.rs index 859c41cbf1..59359ad20b 100644 --- a/aws/sdk/integration-tests/s3/tests/timeouts.rs +++ b/aws/sdk/integration-tests/s3/tests/timeouts.rs @@ -12,13 +12,12 @@ use aws_sdk_s3::types::{ }; use aws_sdk_s3::Client; use aws_smithy_async::assert_elapsed; -use aws_smithy_async::rt::sleep::{default_async_sleep, TokioSleep}; +use aws_smithy_async::rt::sleep::{default_async_sleep, SharedAsyncSleep, TokioSleep}; use aws_smithy_client::never::NeverConnector; use aws_smithy_types::error::display::DisplayErrorContext; use aws_smithy_types::timeout::TimeoutConfig; use std::future::Future; use std::net::SocketAddr; -use std::sync::Arc; use std::time::Duration; use tokio::net::TcpListener; use tokio::time::timeout; @@ -34,7 +33,7 @@ async fn test_timeout_service_ends_request_that_never_completes() { .operation_timeout(Duration::from_secs_f32(0.5)) .build(), ) - .sleep_impl(Arc::new(TokioSleep::new())) + .sleep_impl(SharedAsyncSleep::new(TokioSleep::new())) .build(); let client = Client::new(&sdk_config); diff --git a/aws/sdk/integration-tests/timestreamquery/tests/endpoint_disco.rs b/aws/sdk/integration-tests/timestreamquery/tests/endpoint_disco.rs index a045840907..9d4557b0c3 100644 --- a/aws/sdk/integration-tests/timestreamquery/tests/endpoint_disco.rs +++ b/aws/sdk/integration-tests/timestreamquery/tests/endpoint_disco.rs @@ -6,12 +6,12 @@ use aws_credential_types::provider::SharedCredentialsProvider; use aws_sdk_timestreamquery as query; use aws_sdk_timestreamquery::config::Credentials; +use aws_smithy_async::rt::sleep::SharedAsyncSleep; use aws_smithy_async::test_util::controlled_time_and_sleep; use aws_smithy_async::time::{SharedTimeSource, TimeSource}; use aws_smithy_client::dvr::{MediaType, ReplayingConnection}; use aws_types::region::Region; use aws_types::SdkConfig; -use std::sync::Arc; use std::time::{Duration, UNIX_EPOCH}; #[tokio::test] @@ -24,7 +24,7 @@ async fn do_endpoint_discovery() { let config = SdkConfig::builder() .http_connector(conn.clone()) .region(Region::from_static("us-west-2")) - .sleep_impl(Arc::new(sleep)) + .sleep_impl(SharedAsyncSleep::new(sleep)) .credentials_provider(SharedCredentialsProvider::new(Credentials::for_tests())) .time_source(SharedTimeSource::new(ts.clone())) .build(); diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/ResiliencyConfigCustomization.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/ResiliencyConfigCustomization.kt index 13cc1c26ba..90a03bd348 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/ResiliencyConfigCustomization.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/ResiliencyConfigCustomization.kt @@ -26,8 +26,8 @@ class ResiliencyConfigCustomization(codegenContext: CodegenContext) : ConfigCust private val timeoutModule = RuntimeType.smithyTypes(runtimeConfig).resolve("timeout") private val moduleUseName = codegenContext.moduleUseName() private val codegenScope = arrayOf( - "AsyncSleep" to sleepModule.resolve("AsyncSleep"), "RetryConfig" to retryConfig.resolve("RetryConfig"), + "SharedAsyncSleep" to sleepModule.resolve("SharedAsyncSleep"), "Sleep" to sleepModule.resolve("Sleep"), "TimeoutConfig" to timeoutModule.resolve("TimeoutConfig"), ) @@ -38,7 +38,7 @@ class ResiliencyConfigCustomization(codegenContext: CodegenContext) : ConfigCust is ServiceConfig.ConfigStruct -> rustTemplate( """ retry_config: Option<#{RetryConfig}>, - sleep_impl: Option>, + sleep_impl: Option<#{SharedAsyncSleep}>, timeout_config: Option<#{TimeoutConfig}>, """, *codegenScope, @@ -52,8 +52,8 @@ class ResiliencyConfigCustomization(codegenContext: CodegenContext) : ConfigCust self.retry_config.as_ref() } - /// Return a cloned Arc containing the async sleep implementation from this config, if any. - pub fn sleep_impl(&self) -> Option> { + /// Return a cloned shared async sleep implementation from this config, if any. + pub fn sleep_impl(&self) -> Option<#{SharedAsyncSleep}> { self.sleep_impl.clone() } @@ -70,7 +70,7 @@ class ResiliencyConfigCustomization(codegenContext: CodegenContext) : ConfigCust rustTemplate( """ retry_config: Option<#{RetryConfig}>, - sleep_impl: Option>, + sleep_impl: Option<#{SharedAsyncSleep}>, timeout_config: Option<#{TimeoutConfig}>, """, *codegenScope, @@ -120,7 +120,7 @@ class ResiliencyConfigCustomization(codegenContext: CodegenContext) : ConfigCust /// ## Examples /// /// ```no_run - /// use $moduleUseName::config::{AsyncSleep, Sleep, Config}; + /// use $moduleUseName::config::{AsyncSleep, Config, SharedAsyncSleep, Sleep}; /// /// ##[derive(Debug)] /// pub struct ForeverSleep; @@ -131,10 +131,10 @@ class ResiliencyConfigCustomization(codegenContext: CodegenContext) : ConfigCust /// } /// } /// - /// let sleep_impl = std::sync::Arc::new(ForeverSleep); + /// let sleep_impl = SharedAsyncSleep::new(ForeverSleep); /// let config = Config::builder().sleep_impl(sleep_impl).build(); /// ``` - pub fn sleep_impl(mut self, sleep_impl: std::sync::Arc) -> Self { + pub fn sleep_impl(mut self, sleep_impl: #{SharedAsyncSleep}) -> Self { self.set_sleep_impl(Some(sleep_impl)); self } @@ -144,7 +144,7 @@ class ResiliencyConfigCustomization(codegenContext: CodegenContext) : ConfigCust /// ## Examples /// /// ```no_run - /// use $moduleUseName::config::{AsyncSleep, Sleep, Builder, Config}; + /// use $moduleUseName::config::{AsyncSleep, Builder, Config, SharedAsyncSleep, Sleep}; /// /// ##[derive(Debug)] /// pub struct ForeverSleep; @@ -156,7 +156,7 @@ class ResiliencyConfigCustomization(codegenContext: CodegenContext) : ConfigCust /// } /// /// fn set_never_ending_sleep_impl(builder: &mut Builder) { - /// let sleep_impl = std::sync::Arc::new(ForeverSleep); + /// let sleep_impl = SharedAsyncSleep::new(ForeverSleep); /// builder.set_sleep_impl(Some(sleep_impl)); /// } /// @@ -164,7 +164,7 @@ class ResiliencyConfigCustomization(codegenContext: CodegenContext) : ConfigCust /// set_never_ending_sleep_impl(&mut builder); /// let config = builder.build(); /// ``` - pub fn set_sleep_impl(&mut self, sleep_impl: Option>) -> &mut Self { + pub fn set_sleep_impl(&mut self, sleep_impl: Option<#{SharedAsyncSleep}>) -> &mut Self { self.sleep_impl = sleep_impl; self } @@ -242,7 +242,7 @@ class ResiliencyReExportCustomization(private val runtimeConfig: RuntimeConfig) rustCrate.withModule(ClientRustModule.Config) { rustTemplate( """ - pub use #{sleep}::{AsyncSleep, Sleep}; + pub use #{sleep}::{AsyncSleep, SharedAsyncSleep, Sleep}; /// Retry configuration /// diff --git a/rust-runtime/aws-smithy-async/src/rt/sleep.rs b/rust-runtime/aws-smithy-async/src/rt/sleep.rs index 4ea9f70ed5..076db95c97 100644 --- a/rust-runtime/aws-smithy-async/src/rt/sleep.rs +++ b/rust-runtime/aws-smithy-async/src/rt/sleep.rs @@ -39,15 +39,44 @@ where } } +/// Wrapper type for sharable `AsyncSleep` +#[derive(Clone, Debug)] +pub struct SharedAsyncSleep(Arc); + +impl SharedAsyncSleep { + /// Create a new `SharedAsyncSleep` from `AsyncSleep` + pub fn new(sleep: impl AsyncSleep + 'static) -> Self { + Self(Arc::new(sleep)) + } +} + +impl AsRef for SharedAsyncSleep { + fn as_ref(&self) -> &(dyn AsyncSleep + 'static) { + self.0.as_ref() + } +} + +impl From> for SharedAsyncSleep { + fn from(sleep: Arc) -> Self { + SharedAsyncSleep(sleep) + } +} + +impl AsyncSleep for SharedAsyncSleep { + fn sleep(&self, duration: Duration) -> Sleep { + self.0.sleep(duration) + } +} + #[cfg(feature = "rt-tokio")] /// Returns a default sleep implementation based on the features enabled -pub fn default_async_sleep() -> Option> { - Some(sleep_tokio()) +pub fn default_async_sleep() -> Option { + Some(SharedAsyncSleep::from(sleep_tokio())) } #[cfg(not(feature = "rt-tokio"))] /// Returns a default sleep implementation based on the features enabled -pub fn default_async_sleep() -> Option> { +pub fn default_async_sleep() -> Option { None } diff --git a/rust-runtime/aws-smithy-client/src/builder.rs b/rust-runtime/aws-smithy-client/src/builder.rs index 063c9a6a47..5602c330f5 100644 --- a/rust-runtime/aws-smithy-client/src/builder.rs +++ b/rust-runtime/aws-smithy-client/src/builder.rs @@ -4,12 +4,11 @@ */ use crate::{bounds, erase, retry, Client}; -use aws_smithy_async::rt::sleep::{default_async_sleep, AsyncSleep}; +use aws_smithy_async::rt::sleep::{default_async_sleep, SharedAsyncSleep}; use aws_smithy_http::body::SdkBody; use aws_smithy_http::result::ConnectorError; use aws_smithy_types::retry::ReconnectMode; use aws_smithy_types::timeout::{OperationTimeoutConfig, TimeoutConfig}; -use std::sync::Arc; #[derive(Clone, Debug)] struct MaybeRequiresSleep { @@ -37,7 +36,7 @@ pub struct Builder { middleware: M, retry_policy: MaybeRequiresSleep, operation_timeout_config: Option, - sleep_impl: Option>, + sleep_impl: Option, reconnect_mode: Option, } @@ -312,14 +311,14 @@ impl Builder { self } - /// Set the [`AsyncSleep`] function that the [`Client`] will use to create things like timeout futures. - pub fn set_sleep_impl(&mut self, async_sleep: Option>) -> &mut Self { + /// Set [`aws_smithy_async::rt::sleep::SharedAsyncSleep`] that the [`Client`] will use to create things like timeout futures. + pub fn set_sleep_impl(&mut self, async_sleep: Option) -> &mut Self { self.sleep_impl = async_sleep; self } - /// Set the [`AsyncSleep`] function that the [`Client`] will use to create things like timeout futures. - pub fn sleep_impl(mut self, async_sleep: Arc) -> Self { + /// Set [`aws_smithy_async::rt::sleep::SharedAsyncSleep`] that the [`Client`] will use to create things like timeout futures. + pub fn sleep_impl(mut self, async_sleep: SharedAsyncSleep) -> Self { self.set_sleep_impl(Some(async_sleep)); self } @@ -458,7 +457,7 @@ where mod tests { use super::*; use crate::never::NeverConnector; - use aws_smithy_async::rt::sleep::Sleep; + use aws_smithy_async::rt::sleep::{AsyncSleep, Sleep}; use std::panic::{self, AssertUnwindSafe}; use std::time::Duration; diff --git a/rust-runtime/aws-smithy-client/src/conns.rs b/rust-runtime/aws-smithy-client/src/conns.rs index 21d6f5e80e..d4e25c45aa 100644 --- a/rust-runtime/aws-smithy-client/src/conns.rs +++ b/rust-runtime/aws-smithy-client/src/conns.rs @@ -54,13 +54,12 @@ lazy_static::lazy_static! { mod default_connector { use crate::erase::DynConnector; use crate::http_connector::ConnectorSettings; - use aws_smithy_async::rt::sleep::AsyncSleep; - use std::sync::Arc; + use aws_smithy_async::rt::sleep::SharedAsyncSleep; #[cfg(feature = "rustls")] fn base( settings: &ConnectorSettings, - sleep: Option>, + sleep: Option, ) -> crate::hyper_ext::Builder { let mut hyper = crate::hyper_ext::Adapter::builder().connector_settings(settings.clone()); if let Some(sleep) = sleep { @@ -69,10 +68,10 @@ mod default_connector { hyper } - /// Given `ConnectorSettings` and an `AsyncSleep`, create a `DynConnector` from defaults depending on what cargo features are activated. + /// Given `ConnectorSettings` and an `SharedAsyncSleep`, create a `DynConnector` from defaults depending on what cargo features are activated. pub fn default_connector( settings: &ConnectorSettings, - sleep: Option>, + sleep: Option, ) -> Option { #[cfg(feature = "rustls")] { diff --git a/rust-runtime/aws-smithy-client/src/http_connector.rs b/rust-runtime/aws-smithy-client/src/http_connector.rs index 67db6e6918..37366604ee 100644 --- a/rust-runtime/aws-smithy-client/src/http_connector.rs +++ b/rust-runtime/aws-smithy-client/src/http_connector.rs @@ -7,14 +7,14 @@ //! that enable passing HTTP connectors around. use crate::erase::DynConnector; -use aws_smithy_async::rt::sleep::AsyncSleep; +use aws_smithy_async::rt::sleep::SharedAsyncSleep; use aws_smithy_types::timeout::TimeoutConfig; use std::time::Duration; use std::{fmt::Debug, sync::Arc}; /// Type alias for a Connector factory function. pub type MakeConnectorFn = - dyn Fn(&ConnectorSettings, Option>) -> Option + Send + Sync; + dyn Fn(&ConnectorSettings, Option) -> Option + Send + Sync; /// Enum for describing the two "kinds" of HTTP Connectors in smithy-rs. #[derive(Clone)] @@ -47,7 +47,7 @@ impl HttpConnector { pub fn connector( &self, settings: &ConnectorSettings, - sleep: Option>, + sleep: Option, ) -> Option { match self { HttpConnector::Prebuilt(conn) => conn.clone(), diff --git a/rust-runtime/aws-smithy-client/src/hyper_ext.rs b/rust-runtime/aws-smithy-client/src/hyper_ext.rs index 8f0ca40609..be1e5679d2 100644 --- a/rust-runtime/aws-smithy-client/src/hyper_ext.rs +++ b/rust-runtime/aws-smithy-client/src/hyper_ext.rs @@ -81,7 +81,7 @@ use crate::http_connector::ConnectorSettings; use crate::hyper_ext::timeout_middleware::{ConnectTimeout, HttpReadTimeout, HttpTimeoutError}; use crate::never::stream::EmptyStream; use aws_smithy_async::future::timeout::TimedOutError; -use aws_smithy_async::rt::sleep::{default_async_sleep, AsyncSleep}; +use aws_smithy_async::rt::sleep::{default_async_sleep, SharedAsyncSleep}; use aws_smithy_http::body::SdkBody; use aws_smithy_http::result::ConnectorError; @@ -95,8 +95,6 @@ use hyper::client::connect::{ use std::error::Error; use std::fmt::Debug; -use std::sync::Arc; - use crate::erase::boxclone::BoxFuture; use aws_smithy_http::connection::{CaptureSmithyConnection, ConnectionMetadata}; use tokio::io::{AsyncRead, AsyncWrite}; @@ -252,7 +250,7 @@ fn find_source<'a, E: Error + 'static>(err: &'a (dyn Error + 'static)) -> Option #[derive(Default, Debug)] pub struct Builder { connector_settings: Option, - sleep_impl: Option>, + sleep_impl: Option, client_builder: Option, } @@ -288,9 +286,7 @@ impl Builder { let read_timeout = match read_timeout { Some(duration) => HttpReadTimeout::new( base, - sleep_impl - .clone() - .expect("a sleep impl must be provided in order to have a read timeout"), + sleep_impl.expect("a sleep impl must be provided in order to have a read timeout"), duration, ), None => HttpReadTimeout::no_timeout(base), @@ -304,7 +300,7 @@ impl Builder { /// /// Calling this is only necessary for testing or to use something other than /// [`default_async_sleep`]. - pub fn sleep_impl(mut self, sleep_impl: Arc) -> Self { + pub fn sleep_impl(mut self, sleep_impl: SharedAsyncSleep) -> Self { self.sleep_impl = Some(sleep_impl); self } @@ -313,10 +309,7 @@ impl Builder { /// /// Calling this is only necessary for testing or to use something other than /// [`default_async_sleep`]. - pub fn set_sleep_impl( - &mut self, - sleep_impl: Option>, - ) -> &mut Self { + pub fn set_sleep_impl(&mut self, sleep_impl: Option) -> &mut Self { self.sleep_impl = sleep_impl; self } @@ -361,7 +354,6 @@ mod timeout_middleware { use std::fmt::Formatter; use std::future::Future; use std::pin::Pin; - use std::sync::Arc; use std::task::{Context, Poll}; use std::time::Duration; @@ -370,8 +362,8 @@ mod timeout_middleware { use tower::BoxError; use aws_smithy_async::future::timeout::{TimedOutError, Timeout}; - use aws_smithy_async::rt::sleep::AsyncSleep; use aws_smithy_async::rt::sleep::Sleep; + use aws_smithy_async::rt::sleep::{AsyncSleep, SharedAsyncSleep}; #[derive(Debug)] pub(crate) struct HttpTimeoutError { @@ -405,14 +397,14 @@ mod timeout_middleware { #[derive(Clone, Debug)] pub(super) struct ConnectTimeout { inner: I, - timeout: Option<(Arc, Duration)>, + timeout: Option<(SharedAsyncSleep, Duration)>, } impl ConnectTimeout { /// Create a new `ConnectTimeout` around `inner`. /// /// Typically, `I` will implement [`hyper::client::connect::Connect`]. - pub(crate) fn new(inner: I, sleep: Arc, timeout: Duration) -> Self { + pub(crate) fn new(inner: I, sleep: SharedAsyncSleep, timeout: Duration) -> Self { Self { inner, timeout: Some((sleep, timeout)), @@ -430,14 +422,14 @@ mod timeout_middleware { #[derive(Clone, Debug)] pub(crate) struct HttpReadTimeout { inner: I, - timeout: Option<(Arc, Duration)>, + timeout: Option<(SharedAsyncSleep, Duration)>, } impl HttpReadTimeout { /// Create a new `HttpReadTimeout` around `inner`. /// /// Typically, `I` will implement [`tower::Service>`]. - pub(crate) fn new(inner: I, sleep: Arc, timeout: Duration) -> Self { + pub(crate) fn new(inner: I, sleep: SharedAsyncSleep, timeout: Duration) -> Self { Self { inner, timeout: Some((sleep, timeout)), @@ -565,11 +557,10 @@ mod timeout_middleware { use crate::hyper_ext::Adapter; use crate::never::{NeverConnected, NeverReplies}; use aws_smithy_async::assert_elapsed; - use aws_smithy_async::rt::sleep::TokioSleep; + use aws_smithy_async::rt::sleep::{SharedAsyncSleep, TokioSleep}; use aws_smithy_http::body::SdkBody; use aws_smithy_types::error::display::DisplayErrorContext; use aws_smithy_types::timeout::TimeoutConfig; - use std::sync::Arc; use std::time::Duration; use tower::Service; @@ -591,7 +582,7 @@ mod timeout_middleware { ); let mut hyper = Adapter::builder() .connector_settings(connector_settings) - .sleep_impl(Arc::new(TokioSleep::new())) + .sleep_impl(SharedAsyncSleep::new(TokioSleep::new())) .build(inner); let now = tokio::time::Instant::now(); tokio::time::pause(); @@ -630,7 +621,7 @@ mod timeout_middleware { ); let mut hyper = Adapter::builder() .connector_settings(connector_settings) - .sleep_impl(Arc::new(TokioSleep::new())) + .sleep_impl(SharedAsyncSleep::new(TokioSleep::new())) .build(inner); let now = tokio::time::Instant::now(); tokio::time::pause(); diff --git a/rust-runtime/aws-smithy-client/src/lib.rs b/rust-runtime/aws-smithy-client/src/lib.rs index 7d3a6f256e..935dddd2f0 100644 --- a/rust-runtime/aws-smithy-client/src/lib.rs +++ b/rust-runtime/aws-smithy-client/src/lib.rs @@ -51,7 +51,7 @@ pub mod hyper_ext; pub mod static_tests; use crate::poison::PoisonLayer; -use aws_smithy_async::rt::sleep::AsyncSleep; +use aws_smithy_async::rt::sleep::SharedAsyncSleep; use aws_smithy_http::operation::Operation; use aws_smithy_http::response::ParseHttpResponse; @@ -62,7 +62,6 @@ use aws_smithy_http_tower::parse_response::ParseResponseLayer; use aws_smithy_types::error::display::DisplayErrorContext; use aws_smithy_types::retry::{ProvideErrorKind, ReconnectMode}; use aws_smithy_types::timeout::OperationTimeoutConfig; -use std::sync::Arc; use timeout::ClientTimeoutParams; pub use timeout::TimeoutLayer; use tower::{Service, ServiceBuilder, ServiceExt}; @@ -97,7 +96,7 @@ pub struct Client< retry_policy: RetryPolicy, reconnect_mode: ReconnectMode, operation_timeout_config: OperationTimeoutConfig, - sleep_impl: Option>, + sleep_impl: Option, } impl Client<(), (), ()> { diff --git a/rust-runtime/aws-smithy-client/src/retry.rs b/rust-runtime/aws-smithy-client/src/retry.rs index 2c38807fae..8c2fdc246c 100644 --- a/rust-runtime/aws-smithy-client/src/retry.rs +++ b/rust-runtime/aws-smithy-client/src/retry.rs @@ -19,7 +19,7 @@ use std::time::Duration; use tracing::Instrument; -use aws_smithy_async::rt::sleep::AsyncSleep; +use aws_smithy_async::rt::sleep::{AsyncSleep, SharedAsyncSleep}; use aws_smithy_http::operation::Operation; use aws_smithy_http::retry::ClassifyRetry; @@ -40,7 +40,7 @@ where type Policy; /// Create a new policy mechanism instance. - fn new_request_policy(&self, sleep_impl: Option>) -> Self::Policy; + fn new_request_policy(&self, sleep_impl: Option) -> Self::Policy; } /// Retry Policy Configuration @@ -165,7 +165,7 @@ impl Standard { impl NewRequestPolicy for Standard { type Policy = RetryHandler; - fn new_request_policy(&self, sleep_impl: Option>) -> Self::Policy { + fn new_request_policy(&self, sleep_impl: Option) -> Self::Policy { RetryHandler { local: RequestLocalRetryState::new(), shared: self.shared_state.clone(), @@ -262,7 +262,7 @@ pub struct RetryHandler { local: RequestLocalRetryState, shared: CrossRequestRetryState, config: Config, - sleep_impl: Option>, + sleep_impl: Option, } #[cfg(test)] diff --git a/rust-runtime/aws-smithy-client/src/timeout.rs b/rust-runtime/aws-smithy-client/src/timeout.rs index 640e1c4562..f9a03a41f6 100644 --- a/rust-runtime/aws-smithy-client/src/timeout.rs +++ b/rust-runtime/aws-smithy-client/src/timeout.rs @@ -7,13 +7,12 @@ use crate::SdkError; use aws_smithy_async::future::timeout::Timeout; -use aws_smithy_async::rt::sleep::{AsyncSleep, Sleep}; +use aws_smithy_async::rt::sleep::{AsyncSleep, SharedAsyncSleep, Sleep}; use aws_smithy_http::operation::Operation; use aws_smithy_types::timeout::OperationTimeoutConfig; use pin_project_lite::pin_project; use std::future::Future; use std::pin::Pin; -use std::sync::Arc; use std::task::{Context, Poll}; use std::time::Duration; use tower::Layer; @@ -46,7 +45,7 @@ pub struct TimeoutServiceParams { /// The kind of timeouts created from these params kind: &'static str, /// The AsyncSleep impl that will be used to create time-limited futures - async_sleep: Arc, + async_sleep: SharedAsyncSleep, } #[derive(Clone, Debug, Default)] @@ -61,7 +60,7 @@ pub(crate) struct ClientTimeoutParams { impl ClientTimeoutParams { pub(crate) fn new( timeout_config: &OperationTimeoutConfig, - async_sleep: Option>, + async_sleep: Option, ) -> Self { if let Some(async_sleep) = async_sleep { Self { @@ -232,11 +231,10 @@ mod test { use crate::never::NeverService; use crate::{SdkError, TimeoutLayer}; use aws_smithy_async::assert_elapsed; - use aws_smithy_async::rt::sleep::{AsyncSleep, TokioSleep}; + use aws_smithy_async::rt::sleep::{SharedAsyncSleep, TokioSleep}; use aws_smithy_http::body::SdkBody; use aws_smithy_http::operation::{Operation, Request}; use aws_smithy_types::timeout::TimeoutConfig; - use std::sync::Arc; use std::time::Duration; use tower::{Service, ServiceBuilder, ServiceExt}; @@ -250,7 +248,7 @@ mod test { .operation_timeout(Duration::from_secs_f32(0.25)) .build(), ); - let sleep_impl: Arc = Arc::new(TokioSleep::new()); + let sleep_impl = SharedAsyncSleep::new(TokioSleep::new()); let timeout_service_params = ClientTimeoutParams::new(&timeout_config, Some(sleep_impl)); let mut svc = ServiceBuilder::new() .layer(TimeoutLayer::new(timeout_service_params.operation_timeout)) diff --git a/rust-runtime/aws-smithy-client/tests/e2e_test.rs b/rust-runtime/aws-smithy-client/tests/e2e_test.rs index 0a8594d6b3..f18a084bb5 100644 --- a/rust-runtime/aws-smithy-client/tests/e2e_test.rs +++ b/rust-runtime/aws-smithy-client/tests/e2e_test.rs @@ -5,14 +5,13 @@ mod test_operation; use crate::test_operation::{TestOperationParser, TestRetryClassifier}; -use aws_smithy_async::rt::sleep::TokioSleep; +use aws_smithy_async::rt::sleep::{SharedAsyncSleep, TokioSleep}; use aws_smithy_client::test_connection::TestConnection; use aws_smithy_client::Client; use aws_smithy_http::body::SdkBody; use aws_smithy_http::operation; use aws_smithy_http::operation::Operation; use aws_smithy_http::result::SdkError; -use std::sync::Arc; use std::time::Duration; use tower::layer::util::Identity; @@ -72,7 +71,7 @@ async fn end_to_end_retry_test() { .connector(conn.clone()) .middleware(Identity::new()) .retry_config(retry_config) - .sleep_impl(Arc::new(TokioSleep::new())) + .sleep_impl(SharedAsyncSleep::new(TokioSleep::new())) .build(); tokio::time::pause(); let initial = tokio::time::Instant::now(); diff --git a/rust-runtime/aws-smithy-client/tests/reconnect_on_transient_error.rs b/rust-runtime/aws-smithy-client/tests/reconnect_on_transient_error.rs index 475c076b12..3fc0fe133a 100644 --- a/rust-runtime/aws-smithy-client/tests/reconnect_on_transient_error.rs +++ b/rust-runtime/aws-smithy-client/tests/reconnect_on_transient_error.rs @@ -7,7 +7,7 @@ mod test_operation; -use aws_smithy_async::rt::sleep::TokioSleep; +use aws_smithy_async::rt::sleep::{SharedAsyncSleep, TokioSleep}; use aws_smithy_client::test_connection::wire_mock; use aws_smithy_client::test_connection::wire_mock::{check_matches, RecordedEvent, ReplayedEvent}; use aws_smithy_client::{hyper_ext, Builder}; @@ -21,7 +21,6 @@ use http::Uri; use http_body::combinators::BoxBody; use hyper::client::{Builder as HyperBuilder, HttpConnector}; use std::convert::Infallible; -use std::sync::Arc; use std::time::Duration; use test_operation::{TestOperationParser, TestRetryClassifier}; use tower::layer::util::Identity; @@ -94,7 +93,7 @@ async fn wire_level_test( .operation_attempt_timeout(Duration::from_millis(100)) .build(), )) - .sleep_impl(Arc::new(TokioSleep::new())) + .sleep_impl(SharedAsyncSleep::new(TokioSleep::new())) .build(); loop { match client diff --git a/rust-runtime/aws-smithy-runtime-api/src/client/orchestrator.rs b/rust-runtime/aws-smithy-runtime-api/src/client/orchestrator.rs index 6e041566ea..f60801d026 100644 --- a/rust-runtime/aws-smithy-runtime-api/src/client/orchestrator.rs +++ b/rust-runtime/aws-smithy-runtime-api/src/client/orchestrator.rs @@ -12,7 +12,7 @@ use crate::client::interceptors::context::{Error, Input, Output}; use crate::client::retries::RetryClassifiers; use crate::client::retries::RetryStrategy; use aws_smithy_async::future::now_or_later::NowOrLater; -use aws_smithy_async::rt::sleep::AsyncSleep; +use aws_smithy_async::rt::sleep::SharedAsyncSleep; use aws_smithy_async::time::{SharedTimeSource, TimeSource}; use aws_smithy_http::body::SdkBody; use aws_smithy_types::config_bag::ConfigBag; @@ -141,8 +141,8 @@ pub trait ConfigBagAccessors { fn request_time(&self) -> Option; fn set_request_time(&mut self, time_source: impl TimeSource + 'static); - fn sleep_impl(&self) -> Option>; - fn set_sleep_impl(&mut self, async_sleep: Option>); + fn sleep_impl(&self) -> Option; + fn set_sleep_impl(&mut self, async_sleep: Option); fn loaded_request_body(&self) -> &LoadedRequestBody; fn set_loaded_request_body(&mut self, loaded_request_body: LoadedRequestBody); @@ -271,15 +271,15 @@ impl ConfigBagAccessors for ConfigBag { self.put::(SharedTimeSource::new(request_time)); } - fn sleep_impl(&self) -> Option> { - self.get::>().cloned() + fn sleep_impl(&self) -> Option { + self.get::().cloned() } - fn set_sleep_impl(&mut self, sleep_impl: Option>) { + fn set_sleep_impl(&mut self, sleep_impl: Option) { if let Some(sleep_impl) = sleep_impl { - self.put::>(sleep_impl); + self.put::(sleep_impl); } else { - self.unset::>(); + self.unset::(); } } diff --git a/rust-runtime/aws-smithy-runtime/src/client/orchestrator.rs b/rust-runtime/aws-smithy-runtime/src/client/orchestrator.rs index f626816dce..34d5d34dd5 100644 --- a/rust-runtime/aws-smithy-runtime/src/client/orchestrator.rs +++ b/rust-runtime/aws-smithy-runtime/src/client/orchestrator.rs @@ -7,6 +7,7 @@ use self::auth::orchestrate_auth; use crate::client::orchestrator::endpoints::orchestrate_endpoint; use crate::client::orchestrator::http::read_body; use crate::client::timeout::{MaybeTimeout, ProvideMaybeTimeoutConfig, TimeoutKind}; +use aws_smithy_async::rt::sleep::AsyncSleep; use aws_smithy_http::body::SdkBody; use aws_smithy_http::byte_stream::ByteStream; use aws_smithy_http::result::SdkError; diff --git a/rust-runtime/aws-smithy-runtime/src/client/timeout.rs b/rust-runtime/aws-smithy-runtime/src/client/timeout.rs index b54447194c..2f663b2e60 100644 --- a/rust-runtime/aws-smithy-runtime/src/client/timeout.rs +++ b/rust-runtime/aws-smithy-runtime/src/client/timeout.rs @@ -4,7 +4,7 @@ */ use aws_smithy_async::future::timeout::Timeout; -use aws_smithy_async::rt::sleep::{AsyncSleep, Sleep}; +use aws_smithy_async::rt::sleep::{AsyncSleep, SharedAsyncSleep, Sleep}; use aws_smithy_client::SdkError; use aws_smithy_runtime_api::client::orchestrator::{ConfigBagAccessors, HttpResponse}; use aws_smithy_types::config_bag::ConfigBag; @@ -12,7 +12,6 @@ use aws_smithy_types::timeout::TimeoutConfig; use pin_project_lite::pin_project; use std::future::Future; use std::pin::Pin; -use std::sync::Arc; use std::task::{Context, Poll}; use std::time::Duration; @@ -104,7 +103,7 @@ pub(super) enum TimeoutKind { #[derive(Clone, Debug)] pub(super) struct MaybeTimeoutConfig { - sleep_impl: Option>, + sleep_impl: Option, timeout: Option, timeout_kind: TimeoutKind, } @@ -187,7 +186,7 @@ mod tests { #[tokio::test] async fn test_no_timeout() { - let sleep_impl: Arc = Arc::new(TokioSleep::new()); + let sleep_impl = SharedAsyncSleep::new(TokioSleep::new()); let sleep_future = sleep_impl.sleep(Duration::from_millis(250)); let underlying_future = async { sleep_future.await; @@ -211,7 +210,7 @@ mod tests { #[tokio::test] async fn test_operation_timeout() { - let sleep_impl: Arc = Arc::new(TokioSleep::new()); + let sleep_impl = SharedAsyncSleep::new(TokioSleep::new()); let never = Never::new(); let underlying_future = async { never.await;