2626import software .amazon .awssdk .crt .http .HttpStreamBaseResponseHandler ;
2727import software .amazon .awssdk .http .SdkCancellationException ;
2828import software .amazon .awssdk .http .async .AsyncExecuteRequest ;
29- import software .amazon .awssdk .http .async . SdkAsyncHttpResponseHandler ;
29+ import software .amazon .awssdk .http .crt . internal . request . CrtRequestBodyPublisherSubscriber ;
3030import software .amazon .awssdk .http .crt .internal .response .CrtResponseAdapter ;
3131import software .amazon .awssdk .metrics .MetricCollector ;
3232import software .amazon .awssdk .metrics .NoOpMetricCollector ;
33- import software .amazon .awssdk .utils .Logger ;
3433
3534@ SdkInternalApi
3635public final class CrtAsyncRequestExecutor {
3736
38- private static final Logger log = Logger .loggerFor (CrtAsyncRequestExecutor .class );
39-
4037 public CompletableFuture <Void > execute (CrtAsyncRequestContext executionContext ) {
4138 AsyncExecuteRequest asyncRequest = executionContext .sdkRequest ();
4239 CompletableFuture <Void > requestFuture = createAsyncExecutionFuture (asyncRequest );
40+ ResponseHandlerErrorNotifier errorNotifier = new ResponseHandlerErrorNotifier (asyncRequest .responseHandler ());
4341
4442 try {
45- doExecute (executionContext , asyncRequest , requestFuture );
43+ doExecute (executionContext , asyncRequest , requestFuture , errorNotifier );
4644 } catch (Throwable t ) {
47- reportAsyncFailure (t , requestFuture , asyncRequest . responseHandler () );
45+ reportAsyncFailure (t , requestFuture , errorNotifier );
4846 }
4947
5048 return requestFuture ;
5149 }
5250
5351 private void doExecute (CrtAsyncRequestContext executionContext ,
5452 AsyncExecuteRequest asyncRequest ,
55- CompletableFuture <Void > requestFuture ) {
53+ CompletableFuture <Void > requestFuture ,
54+ ResponseHandlerErrorNotifier errorNotifier ) {
5655 MetricCollector metricCollector = executionContext .metricCollector ();
5756 boolean shouldPublishMetrics = metricCollector != null && !(metricCollector instanceof NoOpMetricCollector );
5857
@@ -67,28 +66,48 @@ private void doExecute(CrtAsyncRequestContext executionContext,
6766
6867 HttpRequestBase crtRequest = toAsyncCrtRequest (executionContext );
6968
70- CrtStreamHandler streamHandler = new CrtStreamHandler ();
69+ CompletableFuture <HttpStreamBase > streamFuture = new CompletableFuture <>();
70+ CrtStreamHandler streamHandler = new CrtStreamHandler (streamFuture );
7171
7272 HttpStreamBaseResponseHandler crtResponseHandler =
73- CrtResponseAdapter .toCrtResponseHandler (requestFuture , asyncRequest .responseHandler (), streamHandler );
73+ CrtResponseAdapter .toCrtResponseHandler (requestFuture , asyncRequest .responseHandler (), streamHandler , errorNotifier );
7474
75- CompletableFuture < HttpStreamBase > streamFuture =
76- executionContext . streamManager (). acquireStream ( crtRequest , crtResponseHandler );
75+ CrtRequestBodyPublisherSubscriber bodySubscriber =
76+ new CrtRequestBodyPublisherSubscriber ( streamHandler , requestFuture , errorNotifier );
7777
7878 long finalAcquireStartTime = acquireStartTime ;
7979
80- streamFuture .whenComplete ((stream , throwable ) -> {
81- if (shouldPublishMetrics ) {
82- reportMetrics (executionContext .streamManager (), metricCollector , finalAcquireStartTime );
83- }
80+ executionContext .streamManager ().acquireStream (crtRequest , crtResponseHandler , true )
81+ .handle ((stream , throwable ) -> {
82+ if (shouldPublishMetrics ) {
83+ reportMetrics (executionContext .streamManager (), metricCollector , finalAcquireStartTime );
84+ }
85+
86+ if (throwable != null ) {
87+ handleAcquireFailure (throwable , streamFuture , requestFuture , errorNotifier );
88+ return null ;
89+ }
90+ try {
91+ stream .activate ();
92+ streamFuture .complete (stream );
93+ asyncRequest .requestContentPublisher ().subscribe (bodySubscriber );
94+ } catch (Throwable t ) {
95+ handleAcquireFailure (t , streamFuture , requestFuture , errorNotifier );
96+ }
97+ return null ;
98+ }).exceptionally (t -> {
99+ handleAcquireFailure (t , streamFuture , requestFuture , errorNotifier );
100+ return null ;
101+ });
102+ }
84103
85- if ( throwable != null ) {
86- Throwable toThrow = wrapCrtException ( throwable );
87- reportAsyncFailure ( toThrow , requestFuture , asyncRequest . responseHandler ());
88- } else {
89- streamHandler . setStream ( stream );
90- }
91- } );
104+ private void handleAcquireFailure ( Throwable t ,
105+ CompletableFuture < HttpStreamBase > streamFuture ,
106+ CompletableFuture < Void > requestFuture ,
107+ ResponseHandlerErrorNotifier errorNotifier ) {
108+ Throwable toThrow = wrapCrtException ( t );
109+ streamFuture . completeExceptionally ( toThrow );
110+ reportAsyncFailure ( toThrow , requestFuture , errorNotifier );
92111 }
93112
94113 /**
@@ -113,18 +132,10 @@ private CompletableFuture<Void> createAsyncExecutionFuture(AsyncExecuteRequest r
113132 return future ;
114133 }
115134
116- /**
117- * Notify the provided response handler and future of the failure.
118- */
119135 private void reportAsyncFailure (Throwable cause ,
120136 CompletableFuture <Void > executeFuture ,
121- SdkAsyncHttpResponseHandler responseHandler ) {
122- try {
123- responseHandler .onError (cause );
124- } catch (Exception e ) {
125- log .error (() -> "SdkAsyncHttpResponseHandler " + responseHandler + " threw an exception in onError. It will be "
126- + "ignored." , e );
127- }
137+ ResponseHandlerErrorNotifier errorNotifier ) {
138+ errorNotifier .tryNotifyError (cause );
128139 executeFuture .completeExceptionally (cause );
129140 }
130141}
0 commit comments