Skip to content

Commit c055cf1

Browse files
committed
Bypass ConnectionSemaphore when no connection limit is set, close AsyncHttpClient#1467
Motivation: AsyncHttpClient#1379 introduced ConnectionSemaphore to deal with connection limits. When no such limit is set, which is the default, we could bypass all this code. Modification: Don’t create ConnectionSemaphore when no limit is set and bypass all related code when it’s null. Result: More simple code path and possibly better performance
1 parent cbba52f commit c055cf1

File tree

4 files changed

+24
-16
lines changed

4 files changed

+24
-16
lines changed

client/src/main/java/org/asynchttpclient/DefaultAsyncHttpClient.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,13 @@ public class DefaultAsyncHttpClient implements AsyncHttpClient {
4444
private final AsyncHttpClientConfig config;
4545
private final AtomicBoolean closed = new AtomicBoolean(false);
4646
private final ChannelManager channelManager;
47-
private final ConnectionSemaphore connectionSemaphore;
4847
private final NettyRequestSender requestSender;
4948
private final boolean allowStopNettyTimer;
5049
private final Timer nettyTimer;
5150

5251
/**
5352
* Default signature calculator to use for all requests constructed by this
5453
* client instance.
55-
*
56-
* @since 1.1
5754
*/
5855
protected SignatureCalculator signatureCalculator;
5956

@@ -86,7 +83,7 @@ public DefaultAsyncHttpClient(AsyncHttpClientConfig config) {
8683
nettyTimer = allowStopNettyTimer ? newNettyTimer() : config.getNettyTimer();
8784

8885
channelManager = new ChannelManager(config, nettyTimer);
89-
connectionSemaphore = new ConnectionSemaphore(config);
86+
ConnectionSemaphore connectionSemaphore = ConnectionSemaphore.newConnectionSemaphore(config);
9087
requestSender = new NettyRequestSender(config, channelManager, connectionSemaphore, nettyTimer, new AsyncHttpClientState(closed));
9188
channelManager.configureBootstraps(requestSender);
9289
}

client/src/main/java/org/asynchttpclient/netty/NettyResponseFuture.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,14 @@ public final class NettyResponseFuture<V> implements ListenableFuture<V> {
9090
@SuppressWarnings("rawtypes")
9191
private static final AtomicIntegerFieldUpdater<NettyResponseFuture> contentProcessedField = AtomicIntegerFieldUpdater.newUpdater(NettyResponseFuture.class, "contentProcessed");
9292
@SuppressWarnings("rawtypes")
93-
private static final AtomicIntegerFieldUpdater<NettyResponseFuture> onThrowableCalledField = AtomicIntegerFieldUpdater.newUpdater(NettyResponseFuture.class, "onThrowableCalled");
93+
private static final AtomicIntegerFieldUpdater<NettyResponseFuture> onThrowableCalledField = AtomicIntegerFieldUpdater.newUpdater(NettyResponseFuture.class,
94+
"onThrowableCalled");
9495
@SuppressWarnings("rawtypes")
95-
private static final AtomicReferenceFieldUpdater<NettyResponseFuture, TimeoutsHolder> timeoutsHolderField = AtomicReferenceFieldUpdater.newUpdater(NettyResponseFuture.class, TimeoutsHolder.class, "timeoutsHolder");
96+
private static final AtomicReferenceFieldUpdater<NettyResponseFuture, TimeoutsHolder> timeoutsHolderField = AtomicReferenceFieldUpdater.newUpdater(NettyResponseFuture.class,
97+
TimeoutsHolder.class, "timeoutsHolder");
9698
@SuppressWarnings("rawtypes")
97-
private static final AtomicReferenceFieldUpdater<NettyResponseFuture, Object> partitionKeyLockField = AtomicReferenceFieldUpdater.newUpdater(NettyResponseFuture.class, Object.class, "partitionKeyLock");
99+
private static final AtomicReferenceFieldUpdater<NettyResponseFuture, Object> partitionKeyLockField = AtomicReferenceFieldUpdater.newUpdater(NettyResponseFuture.class,
100+
Object.class, "partitionKeyLock");
98101

99102
// volatile where we need CAS ops
100103
private volatile int redirectCount = 0;
@@ -120,12 +123,12 @@ public final class NettyResponseFuture<V> implements ListenableFuture<V> {
120123
private Realm proxyRealm;
121124
public Throwable pendingException;
122125

123-
public NettyResponseFuture(Request originalRequest,//
124-
AsyncHandler<V> asyncHandler,//
125-
NettyRequest nettyRequest,//
126-
int maxRetry,//
127-
ChannelPoolPartitioning connectionPoolPartitioning,//
128-
ConnectionSemaphore connectionSemaphore,//
126+
public NettyResponseFuture(Request originalRequest, //
127+
AsyncHandler<V> asyncHandler, //
128+
NettyRequest nettyRequest, //
129+
int maxRetry, //
130+
ChannelPoolPartitioning connectionPoolPartitioning, //
131+
ConnectionSemaphore connectionSemaphore, //
129132
ProxyServer proxyServer) {
130133

131134
this.asyncHandler = asyncHandler;
@@ -138,6 +141,10 @@ public NettyResponseFuture(Request originalRequest,//
138141
}
139142

140143
private void releasePartitionKeyLock() {
144+
if (connectionSemaphore == null) {
145+
return;
146+
}
147+
141148
Object partitionKey = takePartitionKeyLock();
142149
if (partitionKey != null) {
143150
connectionSemaphore.releaseChannelLock(partitionKey);
@@ -484,7 +491,7 @@ public Object getPartitionKey() {
484491
}
485492

486493
public void acquirePartitionLockLazily() throws IOException {
487-
if (partitionKeyLock != null) {
494+
if (connectionSemaphore == null || partitionKeyLock != null) {
488495
return;
489496
}
490497

client/src/main/java/org/asynchttpclient/netty/channel/ConnectionSemaphore.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
*/
3030
public class ConnectionSemaphore {
3131

32+
public static ConnectionSemaphore newConnectionSemaphore(AsyncHttpClientConfig config) {
33+
return config.getMaxConnections() > 0 || config.getMaxConnectionsPerHost() > 0 ? new ConnectionSemaphore(config) : null;
34+
}
35+
3236
private final int maxTotalConnections;
3337
private final NonBlockingSemaphoreLike freeChannels;
3438
private final int maxConnectionsPerHost;
@@ -37,7 +41,7 @@ public class ConnectionSemaphore {
3741
private final IOException tooManyConnections;
3842
private final IOException tooManyConnectionsPerHost;
3943

40-
public ConnectionSemaphore(AsyncHttpClientConfig config) {
44+
private ConnectionSemaphore(AsyncHttpClientConfig config) {
4145
tooManyConnections = unknownStackTrace(new TooManyConnectionsException(config.getMaxConnections()), ConnectionSemaphore.class, "acquireChannelLock");
4246
tooManyConnectionsPerHost = unknownStackTrace(new TooManyConnectionsPerHostException(config.getMaxConnectionsPerHost()), ConnectionSemaphore.class, "acquireChannelLock");
4347
maxTotalConnections = config.getMaxConnections();

client/src/main/java/org/asynchttpclient/netty/channel/NettyConnectListener.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ private void writeRequest(Channel channel) {
8989

9090
public void onSuccess(Channel channel, InetSocketAddress remoteAddress) {
9191

92-
{
92+
if (connectionSemaphore != null) {
9393
// transfer lock from future to channel
9494
Object partitionKeyLock = future.takePartitionKeyLock();
9595

0 commit comments

Comments
 (0)