Regression: connection managers fail to take into account per route connection config when closing expired connections
This commit is contained in:
parent
233a5bdbb7
commit
fe1e095ef9
|
@ -58,7 +58,6 @@ import org.apache.hc.core5.testing.classic.ClassicTestServer;
|
||||||
import org.apache.hc.core5.util.TimeValue;
|
import org.apache.hc.core5.util.TimeValue;
|
||||||
import org.apache.hc.core5.util.Timeout;
|
import org.apache.hc.core5.util.Timeout;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
|
@ -276,7 +275,7 @@ public class TestConnectionManagement {
|
||||||
connManager.close();
|
connManager.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test @Disabled
|
@Test
|
||||||
public void testCloseExpiredTTLConnections() throws Exception {
|
public void testCloseExpiredTTLConnections() throws Exception {
|
||||||
final ClassicTestServer server = startServer();
|
final ClassicTestServer server = startServer();
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
server.registerHandler("/random/*", new RandomHandler());
|
||||||
|
@ -294,6 +293,7 @@ public class TestConnectionManagement {
|
||||||
);
|
);
|
||||||
|
|
||||||
final PoolingHttpClientConnectionManager connManager = testResources.connManager();
|
final PoolingHttpClientConnectionManager connManager = testResources.connManager();
|
||||||
|
connManager.setMaxTotal(1);
|
||||||
|
|
||||||
final HttpRoute route = new HttpRoute(target, null, false);
|
final HttpRoute route = new HttpRoute(target, null, false);
|
||||||
final HttpContext context = new BasicHttpContext();
|
final HttpContext context = new BasicHttpContext();
|
||||||
|
|
|
@ -107,7 +107,7 @@ public class ConnectionConfig implements Cloneable {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final StringBuilder builder = new StringBuilder();
|
final StringBuilder builder = new StringBuilder();
|
||||||
builder.append("[");
|
builder.append("[");
|
||||||
builder.append(", connectTimeout=").append(connectTimeout);
|
builder.append("connectTimeout=").append(connectTimeout);
|
||||||
builder.append(", socketTimeout=").append(socketTimeout);
|
builder.append(", socketTimeout=").append(socketTimeout);
|
||||||
builder.append(", validateAfterInactivity=").append(validateAfterInactivity);
|
builder.append(", validateAfterInactivity=").append(validateAfterInactivity);
|
||||||
builder.append(", timeToLive=").append(timeToLive);
|
builder.append(", timeToLive=").append(timeToLive);
|
||||||
|
|
|
@ -188,19 +188,33 @@ public class PoolingHttpClientConnectionManager
|
||||||
this.connectionOperator = Args.notNull(httpClientConnectionOperator, "Connection operator");
|
this.connectionOperator = Args.notNull(httpClientConnectionOperator, "Connection operator");
|
||||||
switch (poolConcurrencyPolicy != null ? poolConcurrencyPolicy : PoolConcurrencyPolicy.STRICT) {
|
switch (poolConcurrencyPolicy != null ? poolConcurrencyPolicy : PoolConcurrencyPolicy.STRICT) {
|
||||||
case STRICT:
|
case STRICT:
|
||||||
this.pool = new StrictConnPool<>(
|
this.pool = new StrictConnPool<HttpRoute, ManagedHttpClientConnection>(
|
||||||
DEFAULT_MAX_CONNECTIONS_PER_ROUTE,
|
DEFAULT_MAX_CONNECTIONS_PER_ROUTE,
|
||||||
DEFAULT_MAX_TOTAL_CONNECTIONS,
|
DEFAULT_MAX_TOTAL_CONNECTIONS,
|
||||||
timeToLive,
|
timeToLive,
|
||||||
poolReusePolicy,
|
poolReusePolicy,
|
||||||
null);
|
null) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeExpired() {
|
||||||
|
enumAvailable(e -> closeIfExpired(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
case LAX:
|
case LAX:
|
||||||
this.pool = new LaxConnPool<>(
|
this.pool = new LaxConnPool<HttpRoute, ManagedHttpClientConnection>(
|
||||||
DEFAULT_MAX_CONNECTIONS_PER_ROUTE,
|
DEFAULT_MAX_CONNECTIONS_PER_ROUTE,
|
||||||
timeToLive,
|
timeToLive,
|
||||||
poolReusePolicy,
|
poolReusePolicy,
|
||||||
null);
|
null) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeExpired() {
|
||||||
|
enumAvailable(e -> closeIfExpired(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unexpected PoolConcurrencyPolicy value: " + poolConcurrencyPolicy);
|
throw new IllegalArgumentException("Unexpected PoolConcurrencyPolicy value: " + poolConcurrencyPolicy);
|
||||||
|
@ -570,6 +584,19 @@ public class PoolingHttpClientConnectionManager
|
||||||
this.tlsConfigResolver = tlsConfigResolver;
|
this.tlsConfigResolver = tlsConfigResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void closeIfExpired(final PoolEntry<HttpRoute, ManagedHttpClientConnection> entry) {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
if (entry.getExpiryDeadline().isBefore(now)) {
|
||||||
|
entry.discardConnection(CloseMode.GRACEFUL);
|
||||||
|
} else {
|
||||||
|
final ConnectionConfig connectionConfig = resolveConnectionConfig(entry.getRoute());
|
||||||
|
final TimeValue timeToLive = connectionConfig.getTimeToLive();
|
||||||
|
if (timeToLive != null && Deadline.calculate(entry.getCreated(), timeToLive).isBefore(now)) {
|
||||||
|
entry.discardConnection(CloseMode.GRACEFUL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use custom {@link #setConnectionConfigResolver(Resolver)}
|
* @deprecated Use custom {@link #setConnectionConfigResolver(Resolver)}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -172,19 +172,33 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
|
||||||
this.connectionOperator = Args.notNull(connectionOperator, "Connection operator");
|
this.connectionOperator = Args.notNull(connectionOperator, "Connection operator");
|
||||||
switch (poolConcurrencyPolicy != null ? poolConcurrencyPolicy : PoolConcurrencyPolicy.STRICT) {
|
switch (poolConcurrencyPolicy != null ? poolConcurrencyPolicy : PoolConcurrencyPolicy.STRICT) {
|
||||||
case STRICT:
|
case STRICT:
|
||||||
this.pool = new StrictConnPool<>(
|
this.pool = new StrictConnPool<HttpRoute, ManagedAsyncClientConnection>(
|
||||||
DEFAULT_MAX_CONNECTIONS_PER_ROUTE,
|
DEFAULT_MAX_CONNECTIONS_PER_ROUTE,
|
||||||
DEFAULT_MAX_TOTAL_CONNECTIONS,
|
DEFAULT_MAX_TOTAL_CONNECTIONS,
|
||||||
timeToLive,
|
timeToLive,
|
||||||
poolReusePolicy,
|
poolReusePolicy,
|
||||||
null);
|
null) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeExpired() {
|
||||||
|
enumAvailable(e -> closeIfExpired(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
case LAX:
|
case LAX:
|
||||||
this.pool = new LaxConnPool<>(
|
this.pool = new LaxConnPool<HttpRoute, ManagedAsyncClientConnection>(
|
||||||
DEFAULT_MAX_CONNECTIONS_PER_ROUTE,
|
DEFAULT_MAX_CONNECTIONS_PER_ROUTE,
|
||||||
timeToLive,
|
timeToLive,
|
||||||
poolReusePolicy,
|
poolReusePolicy,
|
||||||
null);
|
null) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeExpired() {
|
||||||
|
enumAvailable(e -> closeIfExpired(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unexpected PoolConcurrencyPolicy value: " + poolConcurrencyPolicy);
|
throw new IllegalArgumentException("Unexpected PoolConcurrencyPolicy value: " + poolConcurrencyPolicy);
|
||||||
|
@ -619,6 +633,19 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
|
||||||
this.tlsConfigResolver = tlsConfigResolver;
|
this.tlsConfigResolver = tlsConfigResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void closeIfExpired(final PoolEntry<HttpRoute, ManagedAsyncClientConnection > entry) {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
if (entry.getExpiryDeadline().isBefore(now)) {
|
||||||
|
entry.discardConnection(CloseMode.GRACEFUL);
|
||||||
|
} else {
|
||||||
|
final ConnectionConfig connectionConfig = resolveConnectionConfig(entry.getRoute());
|
||||||
|
final TimeValue timeToLive = connectionConfig.getTimeToLive();
|
||||||
|
if (timeToLive != null && Deadline.calculate(entry.getCreated(), timeToLive).isBefore(now)) {
|
||||||
|
entry.discardConnection(CloseMode.GRACEFUL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use custom {@link #setConnectionConfigResolver(Resolver)}
|
* @deprecated Use custom {@link #setConnectionConfigResolver(Resolver)}
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue