Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7c77dc2
Enable retries and timeouts by default
vcjana Dec 16, 2025
57679d5
Merge branch 'main' into fix-retry-defaults-clean
aws-sdk-rust-ci Dec 17, 2025
fc83a75
create v2 functions to avoid breaking changes
vcjana Dec 23, 2025
0f588c2
Add tests for retry config behavior version gating
vcjana Jan 6, 2026
efcaf60
Merge branch 'main' into fix-retry-defaults-clean
vcjana Jan 6, 2026
340d295
Fix timeout test to use old behavior version
vcjana Jan 6, 2026
a6a605b
Add allow(deprecated) to tests using old behavior versions
vcjana Jan 6, 2026
0477343
Use DefaultPluginParams and v2025_08_07 per review feedback
vcjana Jan 6, 2026
ea0221e
Add is_aws_sdk flag to enable retries for AWS SDK only
vcjana Jan 6, 2026
64203db
Explicitly disable operation timeouts for AWS SDK to fix timeout merg…
vcjana Jan 6, 2026
9cdf2a6
Fix TimeoutConfigMergingTest to match runtime behavior
vcjana Jan 6, 2026
929a051
Gate retry enablement by awsSdkBuild JSON setting
vcjana Jan 6, 2026
fb0de85
Fix formatting in defaults.rs
vcjana Jan 7, 2026
cb79e9d
Remove is_aws_sdk check from timeout config and add BehaviorVersion t…
vcjana Jan 9, 2026
64509b7
Fix rustfmt formatting
vcjana Jan 9, 2026
952324e
Merge branch 'main' into fix-retry-defaults-clean
vcjana Jan 9, 2026
61347dc
fix rustfmt formatting in timeouts.rs
vcjana Jan 9, 2026
b6fa58c
Rename tests and simplify retry_partition code
vcjana Jan 12, 2026
222a448
Enable retries by default in v2026_01_12 for AWS SDK clients
vcjana Jan 12, 2026
e42152e
Fix docs and version bump for behavior version changes
vcjana Jan 12, 2026
af7b2db
Merge branch 'main' into fix-retry-defaults-clean
vcjana Jan 13, 2026
320eddd
Remove AWS-specific docs from generic client
vcjana Jan 13, 2026
8aa96ab
Pin serde_json to 1.0.146 to fix flaky test
vcjana Jan 13, 2026
cffe1d6
Fix deprecation version and extract timeout constant
vcjana Jan 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class TimeoutConfigMergingTest {
}
}
#{tokio_test}
##[allow(deprecated)]
Comment thread
vcjana marked this conversation as resolved.
Outdated
async fn test_all_timeouts() {
let (_logs, _guard) = capture_test_logs();
let connect_timeout = Duration::from_secs(1);
Expand All @@ -65,6 +66,7 @@ class TimeoutConfigMergingTest {
let operation = Duration::from_secs(4);
let http_client = infallible_client_fn(|_req| http::Response::builder().body(SdkBody::empty()).unwrap());
let sdk_config = SdkConfig::builder()
.behavior_version(aws_smithy_runtime_api::client::behavior_version::BehaviorVersion::v2024_03_28())
.timeout_config(
TimeoutConfig::builder()
.connect_timeout(connect_timeout)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

use aws_sdk_codecatalyst::config::Token;
use aws_sdk_codecatalyst::config::retry::RetryConfig;

#[tokio::test]
async fn sso_bearer_auth() {
Expand All @@ -16,6 +17,7 @@ async fn sso_bearer_auth() {
.with_test_defaults()
.http_client(replay.clone())
.token_provider(Token::new("sso_bearer_auth_test", None))
.retry_config(RetryConfig::disabled())
.build();
let client = aws_sdk_codecatalyst::Client::from_conf(config);

Expand Down
31 changes: 31 additions & 0 deletions aws/sdk/integration-tests/s3/tests/client_construction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ mod with_sdk_config {

mod with_service_config {
use aws_sdk_s3 as s3;
use aws_smithy_runtime_api::client::behavior_version::BehaviorVersion;

#[test]
fn manual_config_construction_all_defaults() {
Expand All @@ -47,4 +48,34 @@ mod with_service_config {
let config = s3::Config::builder().build();
let _s3 = s3::Client::from_conf(config);
}

#[test]
#[allow(deprecated)]
fn test_client_with_new_behavior_version_builds_successfully() {
Comment thread
vcjana marked this conversation as resolved.
Outdated
// With v2025_01_17, retries are enabled by default
// This test verifies the client builds without panicking about missing sleep impl
let config = s3::Config::builder()
.behavior_version(BehaviorVersion::v2025_01_17())
.region(aws_types::region::Region::new("us-east-1"))
.credentials_provider(aws_credential_types::Credentials::for_tests())
.build();

// Should build successfully even though retries are enabled
// (sleep impl is provided by default)
let _client = s3::Client::from_conf(config);
}

#[test]
#[allow(deprecated)]
fn test_client_with_old_behavior_version_builds_successfully() {
// With v2024_03_28, retries are disabled by default
let config = s3::Config::builder()
.behavior_version(BehaviorVersion::v2024_03_28())
.region(aws_types::region::Region::new("us-east-1"))
.credentials_provider(aws_credential_types::Credentials::for_tests())
.build();

// Should build successfully with retries disabled
let _client = s3::Client::from_conf(config);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ class FluentBuilderGenerator(
///
/// By default, any retryable failures will be retried twice. Retry behavior
/// is configurable with the [RetryConfig](aws_smithy_types::retry::RetryConfig), which can be
/// set when configuring the client.
/// set when configuring the client. Note: retries are enabled by default when using
/// `aws_config::load_from_env()` or when using `BehaviorVersion::v2025_01_17()` or later.
Comment thread
vcjana marked this conversation as resolved.
Outdated
pub async fn send(self) -> #{Result}<#{OperationOutput}, #{SdkError}<#{OperationError}, #{HttpResponse}>> {
let input = self.inner.build().map_err(#{SdkError}::construction_failure)?;
let runtime_plugins = #{Operation}::operation_runtime_plugins(
Expand Down
109 changes: 106 additions & 3 deletions rust-runtime/aws-smithy-runtime/src/client/defaults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,37 @@ pub fn default_retry_config_plugin(
)
}

/// Runtime plugin that sets the default retry strategy, config, and partition.
///
/// This version respects the behavior version to enable retries by default for newer versions.
pub fn default_retry_config_plugin_v2(
default_partition_name: impl Into<Cow<'static, str>>,
behavior_version: BehaviorVersion,
Comment thread
vcjana marked this conversation as resolved.
Outdated
) -> Option<SharedRuntimePlugin> {
let retry_partition = RetryPartition::new(default_partition_name);
Comment thread
vcjana marked this conversation as resolved.
Outdated
Some(
default_plugin("default_retry_config_plugin", |components| {
components
.with_retry_strategy(Some(StandardRetryStrategy::new()))
.with_config_validator(SharedConfigValidator::base_client_config_fn(
validate_retry_config,
))
.with_interceptor(TokenBucketProvider::new(retry_partition.clone()))
})
.with_config(layer("default_retry_config", |layer| {
#[allow(deprecated)]
Comment thread
vcjana marked this conversation as resolved.
Outdated
let retry_config = if behavior_version.is_at_least(BehaviorVersion::v2025_01_17()) {
RetryConfig::standard()
} else {
RetryConfig::disabled()
};
layer.store_put(retry_config);
layer.store_put(retry_partition);
}))
Comment thread
vcjana marked this conversation as resolved.
.into_shared(),
)
}

fn validate_retry_config(
components: &RuntimeComponentsBuilder,
cfg: &ConfigBag,
Expand Down Expand Up @@ -181,6 +212,35 @@ pub fn default_timeout_config_plugin() -> Option<SharedRuntimePlugin> {
)
}

/// Runtime plugin that sets the default timeout config.
///
/// This version respects the behavior version to enable connection timeout by default for newer versions.
pub fn default_timeout_config_plugin_v2(
behavior_version: BehaviorVersion,
Comment thread
vcjana marked this conversation as resolved.
Outdated
) -> Option<SharedRuntimePlugin> {
Some(
default_plugin("default_timeout_config_plugin", |components| {
components.with_config_validator(SharedConfigValidator::base_client_config_fn(
validate_timeout_config,
))
})
.with_config(layer("default_timeout_config", |layer| {
#[allow(deprecated)]
let timeout_config = if behavior_version.is_at_least(BehaviorVersion::v2025_01_17()) {
Comment thread
vcjana marked this conversation as resolved.
Outdated
// New behavior: Set connect_timeout, leave others unset
TimeoutConfig::builder()
.connect_timeout(Duration::from_millis(3100))
Comment thread
vcjana marked this conversation as resolved.
Outdated
.build()
} else {
// Old behavior: All timeouts disabled
TimeoutConfig::disabled()
};
layer.store_put(timeout_config);
}))
.into_shared(),
)
}

fn validate_timeout_config(
components: &RuntimeComponentsBuilder,
cfg: &ConfigBag,
Expand Down Expand Up @@ -320,14 +380,15 @@ pub fn default_plugins(
[
default_http_client_plugin_v2(behavior_version),
default_identity_cache_plugin(),
default_retry_config_plugin(
default_retry_config_plugin_v2(
params
.retry_partition_name
.expect("retry_partition_name is required"),
behavior_version,
),
default_sleep_impl_plugin(),
default_time_source_plugin(),
default_timeout_config_plugin(),
default_timeout_config_plugin_v2(behavior_version),
enforce_content_length_runtime_plugin(),
default_stalled_stream_protection_config_plugin_v2(behavior_version),
]
Expand All @@ -339,7 +400,7 @@ pub fn default_plugins(
#[cfg(test)]
mod tests {
use super::*;
use aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugins;
use aws_smithy_runtime_api::client::runtime_plugin::{RuntimePlugin, RuntimePlugins};

fn test_plugin_params(version: BehaviorVersion) -> DefaultPluginParams {
DefaultPluginParams::new()
Expand Down Expand Up @@ -378,4 +439,46 @@ mod tests {
"stalled stream protection on uploads MUST NOT be enabled before v2024_03_28"
);
}

#[test]
#[allow(deprecated)]
fn test_retry_enabled_for_v2025_01_17() {
let plugin = default_retry_config_plugin_v2(
"test-partition",
BehaviorVersion::v2025_01_17(),
)
.expect("plugin should be created");

let config = plugin.config().expect("config should exist");
let retry_config = config
.load::<RetryConfig>()
.expect("retry config should exist");

assert_eq!(
retry_config.max_attempts(),
3,
"retries should be enabled with max_attempts=3 for v2025_01_17"
);
}

#[test]
#[allow(deprecated)]
fn test_retry_disabled_for_old_behavior_version() {
let plugin = default_retry_config_plugin_v2(
"test-partition",
BehaviorVersion::v2024_03_28(),
)
.expect("plugin should be created");

let config = plugin.config().expect("config should exist");
let retry_config = config
.load::<RetryConfig>()
.expect("retry config should exist");

assert_eq!(
retry_config.max_attempts(),
1,
"retries should be disabled with max_attempts=1 for v2024_03_28"
);
}
}
Loading