From ca94e33ad48eca0ecfd51fd712b9931479356f4c Mon Sep 17 00:00:00 2001 From: Kris De Volder Date: Fri, 23 Oct 2020 14:47:15 -0700 Subject: [PATCH] Allow configuring http connection pool size See: https://github.com/docker-java/docker-java/issues/1466 --- .gitignore | 1 + .../httpclient5/ApacheDockerHttpClient.java | 13 +++-- .../ApacheDockerHttpClientImpl.java | 50 +++++++++++-------- .../httpclient5/ConnectionPoolConfig.java | 20 ++++++++ .../httpclient5/ZerodepDockerHttpClient.java | 17 +++++-- 5 files changed, 72 insertions(+), 29 deletions(-) create mode 100644 docker-java-transport-httpclient5/src/main/java/com/github/dockerjava/httpclient5/ConnectionPoolConfig.java diff --git a/.gitignore b/.gitignore index cc29f27cb..201acaa5f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ .project .settings .classpath +.factorypath # Ignore all build/dist directories target diff --git a/docker-java-transport-httpclient5/src/main/java/com/github/dockerjava/httpclient5/ApacheDockerHttpClient.java b/docker-java-transport-httpclient5/src/main/java/com/github/dockerjava/httpclient5/ApacheDockerHttpClient.java index cf2b7300d..10ba2cb09 100644 --- a/docker-java-transport-httpclient5/src/main/java/com/github/dockerjava/httpclient5/ApacheDockerHttpClient.java +++ b/docker-java-transport-httpclient5/src/main/java/com/github/dockerjava/httpclient5/ApacheDockerHttpClient.java @@ -13,6 +13,8 @@ public static final class Builder { private SSLConfig sslConfig = null; + private ConnectionPoolConfig connectionPoolConf = null; + public Builder dockerHost(URI value) { this.dockerHost = Objects.requireNonNull(value, "dockerHost"); return this; @@ -23,13 +25,18 @@ public Builder sslConfig(SSLConfig value) { return this; } + public Builder connectionPool(ConnectionPoolConfig conf) { + this.connectionPoolConf = conf; + return this; + } + public ApacheDockerHttpClient build() { Objects.requireNonNull(dockerHost, "dockerHost"); - return new ApacheDockerHttpClient(dockerHost, sslConfig); + return new ApacheDockerHttpClient(dockerHost, sslConfig, connectionPoolConf); } } - private ApacheDockerHttpClient(URI dockerHost, SSLConfig sslConfig) { - super(dockerHost, sslConfig); + private ApacheDockerHttpClient(URI dockerHost, SSLConfig sslConfig, ConnectionPoolConfig connectionPoolConfig) { + super(dockerHost, sslConfig, connectionPoolConfig); } } diff --git a/docker-java-transport-httpclient5/src/main/java/com/github/dockerjava/httpclient5/ApacheDockerHttpClientImpl.java b/docker-java-transport-httpclient5/src/main/java/com/github/dockerjava/httpclient5/ApacheDockerHttpClientImpl.java index d06bd81ab..c17659d7a 100644 --- a/docker-java-transport-httpclient5/src/main/java/com/github/dockerjava/httpclient5/ApacheDockerHttpClientImpl.java +++ b/docker-java-transport-httpclient5/src/main/java/com/github/dockerjava/httpclient5/ApacheDockerHttpClientImpl.java @@ -41,12 +41,12 @@ class ApacheDockerHttpClientImpl implements DockerHttpClient { private final CloseableHttpClient httpClient; - private final HttpHost host; protected ApacheDockerHttpClientImpl( URI dockerHost, - SSLConfig sslConfig + SSLConfig sslConfig, + ConnectionPoolConfig connectionPoolConf ) { Registry socketFactoryRegistry = createConnectionSocketFactoryRegistry(sslConfig, dockerHost); @@ -66,27 +66,35 @@ protected ApacheDockerHttpClientImpl( host = HttpHost.create(dockerHost); } + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager( + socketFactoryRegistry, + new ManagedHttpClientConnectionFactory( + null, + null, + null, + null, + message -> { + Header transferEncodingHeader = message.getFirstHeader(HttpHeaders.TRANSFER_ENCODING); + if (transferEncodingHeader != null) { + if ("identity".equalsIgnoreCase(transferEncodingHeader.getValue())) { + return ContentLengthStrategy.UNDEFINED; + } + } + return DefaultContentLengthStrategy.INSTANCE.determineLength(message); + }, + null + ) + ); + if (connectionPoolConf != null) { + Integer maxConnections = connectionPoolConf.getMaxConnections(); + if (maxConnections != null) { + connectionManager.setMaxTotal(maxConnections); + connectionManager.setDefaultMaxPerRoute(maxConnections); + } + } httpClient = HttpClients.custom() .setRequestExecutor(new HijackingHttpRequestExecutor(null)) - .setConnectionManager(new PoolingHttpClientConnectionManager( - socketFactoryRegistry, - new ManagedHttpClientConnectionFactory( - null, - null, - null, - null, - message -> { - Header transferEncodingHeader = message.getFirstHeader(HttpHeaders.TRANSFER_ENCODING); - if (transferEncodingHeader != null) { - if ("identity".equalsIgnoreCase(transferEncodingHeader.getValue())) { - return ContentLengthStrategy.UNDEFINED; - } - } - return DefaultContentLengthStrategy.INSTANCE.determineLength(message); - }, - null - ) - )) + .setConnectionManager(connectionManager) .build(); } diff --git a/docker-java-transport-httpclient5/src/main/java/com/github/dockerjava/httpclient5/ConnectionPoolConfig.java b/docker-java-transport-httpclient5/src/main/java/com/github/dockerjava/httpclient5/ConnectionPoolConfig.java new file mode 100644 index 000000000..71d6921d9 --- /dev/null +++ b/docker-java-transport-httpclient5/src/main/java/com/github/dockerjava/httpclient5/ConnectionPoolConfig.java @@ -0,0 +1,20 @@ +package com.github.dockerjava.httpclient5; + +public class ConnectionPoolConfig { + + private Integer maxConnections; + + public Integer getMaxConnections() { + return maxConnections; + } + + public ConnectionPoolConfig setMaxConnections(Integer maxConnections) { + this.maxConnections = maxConnections; + return this; + } + + @Override + public String toString() { + return "ConnectionPoolConfig [maxConnections=" + maxConnections + "]"; + } +} diff --git a/docker-java-transport-zerodep/src/main/java/com/github/dockerjava/httpclient5/ZerodepDockerHttpClient.java b/docker-java-transport-zerodep/src/main/java/com/github/dockerjava/httpclient5/ZerodepDockerHttpClient.java index 2298da816..0dc33205f 100644 --- a/docker-java-transport-zerodep/src/main/java/com/github/dockerjava/httpclient5/ZerodepDockerHttpClient.java +++ b/docker-java-transport-zerodep/src/main/java/com/github/dockerjava/httpclient5/ZerodepDockerHttpClient.java @@ -1,10 +1,10 @@ package com.github.dockerjava.httpclient5; -import com.github.dockerjava.transport.SSLConfig; - import java.net.URI; import java.util.Objects; +import com.github.dockerjava.transport.SSLConfig; + @SuppressWarnings("unused") public final class ZerodepDockerHttpClient extends ApacheDockerHttpClientImpl { @@ -14,6 +14,8 @@ public static final class Builder { private SSLConfig sslConfig = null; + private ConnectionPoolConfig connectionPoolConfig = null; + public Builder dockerHost(URI value) { this.dockerHost = Objects.requireNonNull(value, "dockerHost"); return this; @@ -24,13 +26,18 @@ public Builder sslConfig(SSLConfig value) { return this; } + public Builder connectionPool(ConnectionPoolConfig conf) { + this.connectionPoolConfig = conf; + return this; + } + public ZerodepDockerHttpClient build() { Objects.requireNonNull(dockerHost, "dockerHost"); - return new ZerodepDockerHttpClient(dockerHost, sslConfig); + return new ZerodepDockerHttpClient(dockerHost, sslConfig, connectionPoolConfig); } } - protected ZerodepDockerHttpClient(URI dockerHost, SSLConfig sslConfig) { - super(dockerHost, sslConfig); + protected ZerodepDockerHttpClient(URI dockerHost, SSLConfig sslConfig, ConnectionPoolConfig connectionPoolConf) { + super(dockerHost, sslConfig, connectionPoolConf); } }