Skip to content

Commit 26a49d4

Browse files
authored
Set maxConcurrentStreams on HTTP/2 stream manager so that the MAX_CON… (#6812)
* Set maxConcurrentStreams on HTTP/2 stream manager so that the MAX_CONNECTIONS setting is respected for HTTP/2. Also improved the error message when HTTP/2 is configured with the sync client to clarify available options. * Update http-clients/aws-crt-client/src/main/java/software/amazon/awssdk/http/crt/AwsCrtHttpClientBase.java
1 parent cf3744f commit 26a49d4

File tree

5 files changed

+15
-15
lines changed

5 files changed

+15
-15
lines changed

http-clients/aws-crt-client/src/main/java/software/amazon/awssdk/http/crt/AwsCrtHttpClient.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ public final class AwsCrtHttpClient extends AwsCrtHttpClientBase implements SdkH
5858
private AwsCrtHttpClient(DefaultBuilder builder, AttributeMap config) {
5959
super(builder, config);
6060
if (this.protocol == Protocol.HTTP2) {
61-
throw new UnsupportedOperationException("HTTP/2 is not supported in sync client. Use AwsCrtAsyncHttpClient instead.");
61+
throw new UnsupportedOperationException(
62+
"HTTP/2 is not supported for sync HTTP clients. Either use HTTP/1.1 (the default) or use an async "
63+
+ "HTTP client (e.g., AwsCrtAsyncHttpClient).");
6264
}
6365
}
6466

http-clients/aws-crt-client/src/main/java/software/amazon/awssdk/http/crt/AwsCrtHttpClientBase.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ abstract class AwsCrtHttpClientBase implements SdkAutoCloseable {
6969
private final HttpProxyOptions proxyOptions;
7070
private final HttpMonitoringOptions monitoringOptions;
7171
private final long maxConnectionIdleInMilliseconds;
72-
private final int maxConnectionsPerEndpoint;
72+
private final int maxStreamsPerEndpoint;
7373
private final long connectionAcquisitionTimeout;
7474
private final TlsContextOptions tlsContextOptions;
7575
private boolean isClosed = false;
@@ -95,7 +95,7 @@ abstract class AwsCrtHttpClientBase implements SdkAutoCloseable {
9595
this.tlsContext = registerOwnedResource(clientTlsContext);
9696
this.readBufferSize = builder.getReadBufferSizeInBytes() == null ?
9797
DEFAULT_STREAM_WINDOW_SIZE : builder.getReadBufferSizeInBytes();
98-
this.maxConnectionsPerEndpoint = config.get(SdkHttpConfigurationOption.MAX_CONNECTIONS);
98+
this.maxStreamsPerEndpoint = config.get(SdkHttpConfigurationOption.MAX_CONNECTIONS);
9999
this.monitoringOptions = resolveHttpMonitoringOptions(builder.getConnectionHealthConfiguration()).orElse(null);
100100
this.maxConnectionIdleInMilliseconds = config.get(SdkHttpConfigurationOption.CONNECTION_MAX_IDLE_TIMEOUT).toMillis();
101101
this.connectionAcquisitionTimeout = config.get(SdkHttpConfigurationOption.CONNECTION_ACQUIRE_TIMEOUT).toMillis();
@@ -121,7 +121,7 @@ String clientName() {
121121
}
122122

123123
private HttpStreamManager createConnectionPool(URI uri) {
124-
log.debug(() -> "Creating ConnectionPool for: URI:" + uri + ", MaxConns: " + maxConnectionsPerEndpoint);
124+
log.debug(() -> "Creating ConnectionPool for: URI:" + uri + ", MaxConns: " + maxStreamsPerEndpoint+ ", MaxStreams: " + maxStreamsPerEndpoint);
125125

126126
boolean isHttps = "https".equalsIgnoreCase(uri.getScheme());
127127
TlsContext poolTlsContext = isHttps ? tlsContext : null;
@@ -132,7 +132,7 @@ private HttpStreamManager createConnectionPool(URI uri) {
132132
.withTlsContext(poolTlsContext)
133133
.withUri(uri)
134134
.withWindowSize(readBufferSize)
135-
.withMaxConnections(maxConnectionsPerEndpoint)
135+
.withMaxConnections(maxStreamsPerEndpoint)
136136
.withManualWindowManagement(true)
137137
.withProxyOptions(proxyOptions)
138138
.withMonitoringOptions(monitoringOptions)
@@ -144,6 +144,7 @@ private HttpStreamManager createConnectionPool(URI uri) {
144144

145145
if (protocol == Protocol.HTTP2) {
146146
Http2StreamManagerOptions h2Options = new Http2StreamManagerOptions()
147+
.withMaxConcurrentStreams(maxStreamsPerEndpoint)
147148
.withConnectionManagerOptions(h1Options);
148149

149150
if (!isHttps) {

http-clients/aws-crt-client/src/main/java/software/amazon/awssdk/http/crt/internal/CrtUtils.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
import java.util.concurrent.CompletionException;
2929
import javax.net.ssl.SSLHandshakeException;
3030
import software.amazon.awssdk.annotations.SdkInternalApi;
31+
import software.amazon.awssdk.crt.CRT;
3132
import software.amazon.awssdk.crt.CrtRuntimeException;
32-
import software.amazon.awssdk.crt.http.HttpClientConnection;
3333
import software.amazon.awssdk.crt.http.HttpException;
3434
import software.amazon.awssdk.crt.http.HttpManagerMetrics;
3535
import software.amazon.awssdk.crt.http.HttpStreamManager;
@@ -50,10 +50,7 @@ private CrtUtils() {
5050
public static Throwable wrapWithIoExceptionIfRetryable(HttpException httpException) {
5151
Throwable toThrow = httpException;
5252

53-
// TODO: switch to Crt.awsIsTransientError once https://github.com/awslabs/aws-crt-java/pull/972 is merged
54-
if (HttpClientConnection.isErrorRetryable(httpException)) {
55-
// IOExceptions get retried, and if the CRT says this error is retryable,
56-
// it's semantically an IOException anyway.
53+
if (CRT.awsIsTransientError(httpException.getErrorCode())) {
5754
toThrow = new IOException(httpException);
5855
}
5956
return toThrow;
@@ -70,8 +67,7 @@ public static Throwable wrapCrtException(Throwable throwable) {
7067
if (httpErrorCode == CRT_TLS_NEGOTIATION_ERROR_CODE) {
7168
return new SSLHandshakeException(httpException.getMessage());
7269
}
73-
// TODO: check with CRT team, could CRT_SOCKET_TIMEOUT be thrown
74-
// from processes other than tcp connect?
70+
7571
if (httpErrorCode == CRT_SOCKET_TIMEOUT) {
7672
return new ConnectException(httpException.getMessage());
7773
}

http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/H2ErrorTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import org.junit.jupiter.api.AfterEach;
5656
import org.junit.jupiter.api.BeforeEach;
5757
import org.junit.jupiter.api.Test;
58+
import software.amazon.awssdk.crt.http.HttpException;
5859
import software.amazon.awssdk.http.Protocol;
5960
import software.amazon.awssdk.http.async.SdkAsyncHttpClient;
6061
import software.amazon.awssdk.utils.AttributeMap;
@@ -82,14 +83,14 @@ public void teardown() {
8283
}
8384

8485
@Test
85-
public void serverSendsRstStream_shouldThrowIOException() throws Exception {
86+
public void serverSendsRstStream_shouldNotThrowIOException() throws Exception {
8687
H2ErrorServer server = new H2ErrorServer(ErrorType.RST_STREAM);
8788
server.init();
8889
try {
8990
CompletableFuture<?> request = sendGetRequest(server.port(), client);
9091
assertThatThrownBy(request::join)
9192
.isInstanceOf(CompletionException.class)
92-
.hasCauseInstanceOf(IOException.class)
93+
.hasCauseInstanceOf(HttpException.class)
9394
.hasMessageContaining("RST_STREAM");
9495
} finally {
9596
server.shutdown();

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@
130130
<rxjava3.version>3.1.5</rxjava3.version>
131131
<commons-codec.verion>1.17.1</commons-codec.verion>
132132
<jmh.version>1.37</jmh.version>
133-
<awscrt.version>0.43.5</awscrt.version>
133+
<awscrt.version>0.43.9</awscrt.version>
134134

135135
<!--Test dependencies -->
136136
<junit5.version>5.10.3</junit5.version>

0 commit comments

Comments
 (0)