Skip to content

[Default Read/Write Timeout 3/N] Bake per-service exemption tiers and apply the rollout gate - #7329

Open
zoewangg wants to merge 1 commit into
feature/master/2026-enable-default-read-timeoutfrom
zoewang/enable-default-read-timeout-exemption
Open

[Default Read/Write Timeout 3/N] Bake per-service exemption tiers and apply the rollout gate#7329
zoewangg wants to merge 1 commit into
feature/master/2026-enable-default-read-timeoutfrom
zoewang/enable-default-read-timeout-exemption

Conversation

@zoewangg

Copy link
Copy Markdown
Contributor

Motivation and Context

Increment 3 of N for the default read/write inactivity timeout on the AWS CRT-based HTTP clients. This increment targets the feature branch feature/master/2026-enable-default-read-timeout, on top of increment 1 (the AWS_ENABLE_DEFAULT_READ_TIMEOUT_2026 rollout gate, #7319) and increment 2 (the CRT client applying the resolved SdkHttpConfigurationOption.SDK_INTERNAL_FALLBACK_READ_WRITE_TIMEOUT, #7326).

Not every service should get the same default. Some services stream or hold connections open for long periods, so a single flat inactivity timeout would break them. This increment introduces the per-service exemption tiers and wires the rollout gate to the resolved value:

  • Fully-exempt services get no default read/write timeout.
  • Partially-exempt (long-hold) services get a longer 15-minute timeout.
  • Every other service gets the general 5-minute default.

The per-service tier is independent of the rollout gate and is resolved at code-generation time (service identity does not reach the HTTP client). The gate is then applied once, above the HTTP client, so the value handed is already gate-resolved.

Modifications

Code generation (codegen):

  • New DefaultReadWriteTimeoutExemptionProcessor (registered in DefaultCustomizationProcessor, alongside LongPollingOperationProcessor) reads a checked-in exemption artifact (default-read-write-timeout-exemptions.json, keyed by service sdkId) and bakes each listed service's tier onto the intermediate model: -1 marks a fully-exempt service, a positive value is the timeout in milliseconds.
  • Metadata carries the baked tier (defaultReadWriteTimeoutMillis); BaseClientBuilderClass emits it into the generated serviceHttpConfig() as SDK_INTERNAL_FALLBACK_READ_WRITE_TIMEOUT (Duration.ZERO for fully-exempt, Duration.ofMillis(...) for a positive tier), composing with any existing service HTTP config (e.g. HTTP/2). Services absent from the artifact bake nothing.
  • The processor also exposes a whole-artifact key validation used by the coverage test to fail the build if any artifact key matches no real service sdkId (guards against a stale or mis-cased key silently leaving a service unlisted). Malformed artifact values fail with the offending key and resource named.

aws-core:

  • AwsDefaultClientBuilder.resolveHttpClientConfig applies the rollout gate to the codegen-baked value. The gate is resolved via the AWS_ENABLE_DEFAULT_READ_TIMEOUT_2026 environment variable / system property, else the codegen-baked SdkClientOption.DEFAULT_ENABLE_READ_TIMEOUT_2026 default, else off.
    • Gate on: a baked tier is kept as-is (Duration.ZERO fully-exempt, 15 minutes partial); an unlisted service (nothing baked) gets the flat 5-minute default.
    • Gate off: a baked positive tier (partial) is forced to Duration.ZERO so it cannot apply; otherwise the option is left untouched (an unlisted service stays absent, which is equivalent to Duration.ZERO because the HTTP client's option-absent path applies nothing when the gate is off; a fully-exempt tier is already Duration.ZERO).

The CRT client (increment 2) consumes this resolved value and does not re-evaluate the gate. Other HTTP clients ignore the option. No public API is added or changed.

Testing

  • codegen module builds and tests pass. New tests: DefaultReadWriteTimeoutExemptionProcessorTest (each artifact key bakes its declared tier; case-sensitivity; every key cross-checked against the real service sdkId set; bogus-key guard fires), a full-class fixture-comparison test for the generated serviceHttpConfig() (partial tier composed with HTTP/2), and programmatic emission cases (fully-exempt Duration.ZERO, partial Duration.ofMillis, unlisted omitted).
  • aws-core module builds and tests pass. New AwsDefaultClientBuilderReadWriteTimeoutTest parameterizes the gate/tier matrix (gate off + partial -> ZERO; gate on + unlisted -> 5 min; gate on + fully-exempt -> ZERO; gate on + partial -> 15 min; gate on via codegen default -> 5 min; gate property false overrides the codegen default -> ZERO) plus an explicit case that an unlisted, gated-off service leaves the option absent.
  • Verified against real service models by regenerating samples: SQS (partial) bakes Duration.ofMillis(900000L), Polly (fully-exempt, HTTP/2) composes the HTTP/2 config with Duration.ZERO, STS (unlisted) bakes nothing.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)

Checklist

  • I have read the CONTRIBUTING document
  • Local run of mvn install succeeds (built and tested the affected modules: codegen and aws-core)
  • My code follows the code style of this project
  • My change requires a change to the Javadoc documentation
  • I have updated the Javadoc documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed
  • I have added a changelog entry (deferred to the feature-branch finalization; individual increments on the feature branch do not each add a changelog)

License

  • I confirm that this pull request can be released under the Apache 2 license

Codegen bakes each listed service's default read/write timeout
tier into its generated serviceHttpConfig from a checked-in
exemption artifact; aws-core applies the rollout gate to the
baked value.
@zoewangg
zoewangg requested a review from a team as a code owner August 27, 2026 21:51
@zoewangg
zoewangg requested a review from Fred1155 August 27, 2026 21:54
* The flat default read/write inactivity timeout applied when the rollout gate is on and the service is not listed in the
* codegen exemption artifact.
*/
private static final Duration DEFAULT_READ_WRITE_TIMEOUT = Duration.ofMinutes(5);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the http client is passed in directly, like S3AsyncClient.builder().httpClient(AwsCrtAsyncHttpClient.create())? ServiceHttpConfig() never reaches it in that case, so all service would fall back to the 5 min behavior.

new LowercaseShapeValidatorProcessor(),
new LongPollingOperationProcessor()
new LongPollingOperationProcessor(),
new DefaultReadWriteTimeoutExemptionProcessor()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious: do we intend to remove this processor and the json artifact at the end of the rolling out?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants