Skip to content

Commit c82e627

Browse files
authored
Update documentation (#6837)
1 parent 8ef7f4e commit c82e627

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

core/sdk-core/src/main/java/software/amazon/awssdk/core/async/AsyncRequestBody.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,22 @@ static AsyncRequestBody fromRemainingByteBuffersUnsafe(ByteBuffer... byteBuffers
375375
* <p>An {@link ExecutorService} is required in order to perform the blocking data reads, to prevent blocking the
376376
* non-blocking event loop threads owned by the SDK.
377377
*
378+
* <p><b>Executor Guidance:</b> The provided executor is used to run a blocking task that reads from the input stream and
379+
* pushes data to the HTTP channel. If the executor has fewer threads than the number of concurrent requests using it,
380+
* tasks are serialized — one slow or failing request may block other requests from writing data in a timely manner,
381+
* leading to idle HTTP connections that the server may close before data can be written. This may result in an
382+
* unrecoverable write timeout loop where every retry also fails.
383+
*
384+
* <p>To avoid this:
385+
* <ul>
386+
* <li>Use a <b>dedicated</b> executor for SDK input stream requests — do not share it with other blocking work
387+
* in your application, as competing tasks may delay data writes and cause the same issue.</li>
388+
* <li>Size the executor's thread pool to at least the maximum number of concurrent requests.</li>
389+
* </ul>
390+
*
391+
* <p>It is also recommended to configure an API call timeout via
392+
* {@code ClientOverrideConfiguration.builder().apiCallTimeout()} to bound the total time spent on retries.
393+
*
378394
* @param inputStream The input stream containing the data to be sent
379395
* @param contentLength The content length. If a content length smaller than the actual size of the object is set, the client
380396
* will truncate the stream to the specified content length and only send exactly the number of bytes
@@ -390,7 +406,9 @@ static AsyncRequestBody fromInputStream(InputStream inputStream, Long contentLen
390406

391407
/**
392408
* Creates an {@link AsyncRequestBody} from an {@link InputStream} with the provided
393-
* {@link AsyncRequestBodySplitConfiguration}.
409+
* {@link AsyncRequestBodyFromInputStreamConfiguration}.
410+
*
411+
* <p>See {@link #fromInputStream(InputStream, Long, ExecutorService)} for guidance on executor.
394412
*/
395413
static AsyncRequestBody fromInputStream(AsyncRequestBodyFromInputStreamConfiguration configuration) {
396414
Validate.notNull(configuration, "configuration");

core/sdk-core/src/main/java/software/amazon/awssdk/core/async/AsyncRequestBodyFromInputStreamConfiguration.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ public interface Builder extends CopyableBuilder<AsyncRequestBodyFromInputStream
137137
/**
138138
* Configures the {@link ExecutorService} to perform the blocking data reads.
139139
*
140+
* <p>It is recommended to have a dedicated executor for SDK input stream requests and have as many threads as the
141+
* number of concurrent requests sharing it. Using an undersized or shared executor may lead to unrecoverable failures.
142+
* See {@link AsyncRequestBody#fromInputStream(InputStream, Long, ExecutorService)} for details.
143+
*
140144
* @param executor the executor
141145
* @return This object for method chaining.
142146
*/

0 commit comments

Comments
 (0)