Skip to content

Commit 244e97f

Browse files
committed
Introduce connectionPoolCleanerPeriod so that idle connections are not closed all at once, close AsyncHttpClient#1205
1 parent 0bf50df commit 244e97f

File tree

5 files changed

+31
-7
lines changed

5 files changed

+31
-7
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ public interface AsyncHttpClientConfig {
7070
*/
7171
int getPooledConnectionIdleTimeout();
7272

73+
/**
74+
* @return the period in millis to clean the pool of dead and idle connections.
75+
*/
76+
int getConnectionPoolCleanerPeriod();
77+
7378
/**
7479
* Return the maximum time in millisecond an {@link AsyncHttpClient} waits until the response is completed.
7580
*

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ public class DefaultAsyncHttpClientConfig implements AsyncHttpClientConfig {
8585
// keep-alive
8686
private final boolean keepAlive;
8787
private final int pooledConnectionIdleTimeout;
88+
private final int connectionPoolCleanerPeriod;
8889
private final int connectionTtl;
8990
private final int maxConnections;
9091
private final int maxConnectionsPerHost;
@@ -155,6 +156,7 @@ private DefaultAsyncHttpClientConfig(//
155156
// keep-alive
156157
boolean keepAlive,//
157158
int pooledConnectionIdleTimeout,//
159+
int connectionPoolCleanerPeriod,//
158160
int connectionTtl,//
159161
int maxConnections,//
160162
int maxConnectionsPerHost,//
@@ -226,6 +228,7 @@ private DefaultAsyncHttpClientConfig(//
226228
// keep-alive
227229
this.keepAlive = keepAlive;
228230
this.pooledConnectionIdleTimeout = pooledConnectionIdleTimeout;
231+
this.connectionPoolCleanerPeriod = connectionPoolCleanerPeriod;
229232
this.connectionTtl = connectionTtl;
230233
this.maxConnections = maxConnections;
231234
this.maxConnectionsPerHost = maxConnectionsPerHost;
@@ -373,6 +376,11 @@ public int getPooledConnectionIdleTimeout() {
373376
return pooledConnectionIdleTimeout;
374377
}
375378

379+
@Override
380+
public int getConnectionPoolCleanerPeriod() {
381+
return connectionPoolCleanerPeriod;
382+
}
383+
376384
@Override
377385
public int getConnectionTtl() {
378386
return connectionTtl;
@@ -603,6 +611,7 @@ public static class Builder {
603611
// keep-alive
604612
private boolean keepAlive = defaultKeepAlive();
605613
private int pooledConnectionIdleTimeout = defaultPooledConnectionIdleTimeout();
614+
private int connectionPoolCleanerPeriod = defaultConnectionPoolCleanerPeriod();
606615
private int connectionTtl = defaultConnectionTtl();
607616
private int maxConnections = defaultMaxConnections();
608617
private int maxConnectionsPerHost = defaultMaxConnectionsPerHost();
@@ -1092,6 +1101,7 @@ public DefaultAsyncHttpClientConfig build() {
10921101
shutdownTimeout, //
10931102
keepAlive, //
10941103
pooledConnectionIdleTimeout, //
1104+
connectionPoolCleanerPeriod, //
10951105
connectionTtl, //
10961106
maxConnections, //
10971107
maxConnectionsPerHost, //

client/src/main/java/org/asynchttpclient/config/AsyncHttpClientConfigDefaults.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ public static int defaultPooledConnectionIdleTimeout() {
3939
return AsyncHttpClientConfigHelper.getAsyncHttpClientConfig().getInt(ASYNC_CLIENT_CONFIG_ROOT + "pooledConnectionIdleTimeout");
4040
}
4141

42+
public static int defaultConnectionPoolCleanerPeriod() {
43+
return AsyncHttpClientConfigHelper.getAsyncHttpClientConfig().getInt(ASYNC_CLIENT_CONFIG_ROOT + "connectionPoolCleanerPeriod");
44+
}
45+
4246
public static int defaultReadTimeout() {
4347
return AsyncHttpClientConfigHelper.getAsyncHttpClientConfig().getInt(ASYNC_CLIENT_CONFIG_ROOT + "readTimeout");
4448
}

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

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ public final class DefaultChannelPool implements ChannelPool {
5454
public DefaultChannelPool(AsyncHttpClientConfig config, Timer hashedWheelTimer) {
5555
this(config.getPooledConnectionIdleTimeout(),//
5656
config.getConnectionTtl(),//
57-
hashedWheelTimer);
57+
hashedWheelTimer,//
58+
config.getConnectionPoolCleanerPeriod());
5859
}
5960

6061
private ChannelId channelId(Channel channel) {
@@ -63,17 +64,20 @@ private ChannelId channelId(Channel channel) {
6364

6465
public DefaultChannelPool(int maxIdleTime,//
6566
int connectionTtl,//
66-
Timer nettyTimer) {
67+
Timer nettyTimer,//
68+
int cleanerPeriod) {
6769
this(maxIdleTime,//
6870
connectionTtl,//
6971
PoolLeaseStrategy.LIFO,//
70-
nettyTimer);
72+
nettyTimer,//
73+
cleanerPeriod);
7174
}
7275

7376
public DefaultChannelPool(int maxIdleTime,//
7477
int connectionTtl,//
7578
PoolLeaseStrategy poolLeaseStrategy,//
76-
Timer nettyTimer) {
79+
Timer nettyTimer,//
80+
int cleanerPeriod) {
7781
this.maxIdleTime = (int) maxIdleTime;
7882
this.connectionTtl = connectionTtl;
7983
connectionTtlEnabled = connectionTtl > 0;
@@ -82,7 +86,7 @@ public DefaultChannelPool(int maxIdleTime,//
8286
maxIdleTimeEnabled = maxIdleTime > 0;
8387
this.poolLeaseStrategy = poolLeaseStrategy;
8488

85-
cleanerPeriod = Math.min(connectionTtlEnabled ? connectionTtl : Integer.MAX_VALUE, maxIdleTimeEnabled ? maxIdleTime : Long.MAX_VALUE);
89+
this.cleanerPeriod = Math.min(cleanerPeriod, Math.min(connectionTtlEnabled ? connectionTtl : Integer.MAX_VALUE, maxIdleTimeEnabled ? maxIdleTime : Integer.MAX_VALUE));
8690

8791
if (connectionTtlEnabled || maxIdleTimeEnabled)
8892
scheduleNewIdleChannelDetector(new IdleChannelDetector());
@@ -153,7 +157,7 @@ private List<IdleChannel> expiredChannels(ConcurrentLinkedDeque<IdleChannel> par
153157
if (isIdleTimeoutExpired(idleChannel, now) || isRemotelyClosed(idleChannel.channel) || isTtlExpired(idleChannel.channel, now)) {
154158
LOGGER.debug("Adding Candidate expired Channel {}", idleChannel.channel);
155159
if (idleTimeoutChannels == null)
156-
idleTimeoutChannels = new ArrayList<>();
160+
idleTimeoutChannels = new ArrayList<>(1);
157161
idleTimeoutChannels.add(idleChannel);
158162
}
159163
}
@@ -163,7 +167,7 @@ private List<IdleChannel> expiredChannels(ConcurrentLinkedDeque<IdleChannel> par
163167

164168
private final List<IdleChannel> closeChannels(List<IdleChannel> candidates) {
165169

166-
// lazy create, only if we have a non-closeable channel
170+
// lazy create, only if we hit a non-closeable channel
167171
List<IdleChannel> closedChannels = null;
168172
for (int i = 0; i < candidates.size(); i++) {
169173
// We call takeOwnership here to avoid closing a channel that has just been taken out

client/src/main/resources/ahc-default.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ org.asynchttpclient.maxConnections=-1
33
org.asynchttpclient.maxConnectionsPerHost=-1
44
org.asynchttpclient.connectTimeout=5000
55
org.asynchttpclient.pooledConnectionIdleTimeout=60000
6+
org.asynchttpclient.connectionPoolCleanerPeriod=1000
67
org.asynchttpclient.readTimeout=60000
78
org.asynchttpclient.requestTimeout=60000
89
org.asynchttpclient.connectionTtl=-1

0 commit comments

Comments
 (0)