From a4ec777b96b094bd4b61044b7c18168ded74f2ed Mon Sep 17 00:00:00 2001 From: Zoe Wang <33073555+zoewangg@users.noreply.github.com> Date: Fri, 10 Apr 2026 09:40:19 -0700 Subject: [PATCH] Add a new fromInputStream(InputStream, Long) overload that uses an SDK-managed shared cached thread pool --- .../feature-AWSSDKforJavav2-899dcc8.json | 6 + .../awssdk/core/async/AsyncRequestBody.java | 30 +++- ...questBodyFromInputStreamConfiguration.java | 12 +- ...putStreamWithExecutorAsyncRequestBody.java | 12 +- ...tBodyFromInputStreamConfigurationTest.java | 12 +- ...treamWithExecutorAsyncRequestBodyTest.java | 130 +++++++++++------- .../services/s3/PutObjectIntegrationTest.java | 17 +++ 7 files changed, 151 insertions(+), 68 deletions(-) create mode 100644 .changes/next-release/feature-AWSSDKforJavav2-899dcc8.json diff --git a/.changes/next-release/feature-AWSSDKforJavav2-899dcc8.json b/.changes/next-release/feature-AWSSDKforJavav2-899dcc8.json new file mode 100644 index 000000000000..31711db7727f --- /dev/null +++ b/.changes/next-release/feature-AWSSDKforJavav2-899dcc8.json @@ -0,0 +1,6 @@ +{ + "type": "feature", + "category": "AWS SDK for Java v2", + "contributor": "", + "description": "Added `AsyncRequestBody.fromInputStream(InputStream, Long)` overload that uses an SDK-managed thread pool, removing the need for users to provide their own ExecutorService." +} diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/async/AsyncRequestBody.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/async/AsyncRequestBody.java index 0877557e35bd..36a2d7eb647c 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/async/AsyncRequestBody.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/async/AsyncRequestBody.java @@ -370,16 +370,17 @@ static AsyncRequestBody fromRemainingByteBuffersUnsafe(ByteBuffer... byteBuffers } /** - * Creates an {@link AsyncRequestBody} from an {@link InputStream}. + * Creates an {@link AsyncRequestBody} from an {@link InputStream} with a customer-provided {@link ExecutorService}. * *

An {@link ExecutorService} is required in order to perform the blocking data reads, to prevent blocking the - * non-blocking event loop threads owned by the SDK. + * non-blocking event loop threads owned by the SDK. Consider using {@link #fromInputStream(InputStream, Long)} instead, + * which lets the SDK manage threading internally. * *

Executor Guidance: The provided executor is used to run a blocking task that reads from the input stream and - * pushes data to the HTTP channel. If the executor has fewer threads than the number of concurrent requests using it, + * pushes data to the HTTP connection. If the executor has fewer threads than the number of concurrent requests using it, * tasks are serialized — one slow or failing request may block other requests from writing data in a timely manner, - * leading to idle HTTP connections that the server may close before data can be written. This may result in an - * unrecoverable write timeout loop where every retry also fails. + * leading to idle HTTP connections that the server may close before data can be written. This may result in + * degraded performance or request timeouts. * *

To avoid this: *