Switch CRT HTTP clients (sync and async) from pull-based body to push-based writeData#6993
Open
zoewangg wants to merge 6 commits into
Open
Switch CRT HTTP clients (sync and async) from pull-based body to push-based writeData#6993zoewangg wants to merge 6 commits into
zoewangg wants to merge 6 commits into
Conversation
push-based HttpStreamBase.writeData() API to avoid potential deadlock issue when request body InputStream blocks.
Move stream lifecycle operations (writeData, incrementWindow, releaseConnection, closeConnection) from ResponseHandlerHelper into a dedicated CrtStreamHandler class. This separates header parsing from stream management and makes the shared stream guard explicit between the request executor and response handler. ResponseHandlerHelper now only handles response header parsing.
12 tasks
14bc392 to
7acd52f
Compare
zoewangg
commented
May 27, 2026
7acd52f to
0b4a1bf
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation and Context
AwsCrtHttpClientandAwsCrtAsyncHttpClientcan deadlock when the request body delivers data on or via the CRT event loop thread. TheCRT event loop must never block.
CrtRequestInputStreamAdapter.sendRequestBody()is invoked on the CRT event loop thread and callsInputStream.read(), whichmay block indefinitely if the stream wraps a source that depends on the same event loop thread to make progress (e.g., a
BufferedInputStreamwrapping aResponseInputStream).CrtRequestBodyAdapter.sendRequestBody()is invoked on the CRT event loop thread and pulls from aByteBufferStoringSubscriberwhose subscription is also driven on the event loop. A user-suppliedPublisher<ByteBuffer>that schedulesonNextback onto the same event loop creates the same deadlock risk.Modifications
Migrate from CRT's pull-based body API to the push-based
writeDataAPIacquireStream(request, handler, useManualDataWrites=true)so CRT no longer pulls body bytes from the SDK on the event loop.HttpStreamBase.writeData(byte[], boolean)from outside the event loop (sync caller thread, or a ReactiveStreams subscriber on the async path).
streamHandler.writeData()afterwaitForStream(). Async path drives a newCrtRequestBodyPublisherSubscriberthat pushes eachonNextchunk throughwriteDataand usesrequest(1)for backpressure (next chunkis requested only after the previous
writeDatafuture completes).stream.activate()themselves before completing the SDK-side stream future. CRT's stream manager activates thestream after
complete(stream)returns; without our own activate, a synchronously chainedwriteDatacall would fail withAWS_ERROR_HTTP_STREAM_NOT_ACTIVATED. The C-side activate is idempotent.New shared
CrtStreamHandlertryNotifyResponseHandlerError(handler, t)so the response side and request-body subscriber don't double-deliveronError.CompletableFuture<HttpStreamBase>returned (in spirit) byacquireStream.waitForStream()blocks for synccallers;
writeData(...)chains on stream readiness for async callers.releaseConnection,closeConnection,incrementWindoware silent no-ops if the stream isn't ready (failed-acquire paths).Defensive completion of futures
s.writeData, a publisher whosesubscribethrows,activatethrowing) now reliably fail the corresponding future and tear down the stream so callers see a clear error instead of hanging.Other
CrtRequestInputStreamAdapterandCrtRequestBodyAdapter(no longer used).SubscriberBlackboxVerificationforCrtRequestBodyPublisherSubscriber(and the surefire/TestNG plumbing inthe module pom needed to run it). The TCK exposed two real spec violations that are also fixed: rule 2.3 (
onError/onCompleteMUST NOTcall Subscription methods) and rule 2.5 (a second
onSubscribeMUST be cancelled).aws-crtdependency forwriteDataandacquireStream(request, handler, useManualDataWrites)APIs.Testing
aws-crt-clientunit/functional tests pass (~190 existing + new tests for the subscriber, stream-handler error paths, executordefensive paths, and TCK).
Types of changes
Checklist
mvn installsucceedsscripts/new-changescript and following theinstructions. Commit the new file created by the script in
.changes/next-releasewith your changes.LaunchChangelog
License