Skip to content

Commit

Permalink
Http2 default option tuning and pool usage tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
vietj committed May 28, 2016
1 parent 59e1f29 commit 3afe8bb
Show file tree
Hide file tree
Showing 12 changed files with 209 additions and 78 deletions.
23 changes: 13 additions & 10 deletions src/main/asciidoc/dataobjects.adoc
Expand Up @@ -664,6 +664,19 @@ Add an enabled SSL/TLS protocols
Set to <code>true</code> when an <i>h2c</i> connection is established using an HTTP/1.1 upgrade request, and <code>false</code> Set to <code>true</code> when an <i>h2c</i> connection is established using an HTTP/1.1 upgrade request, and <code>false</code>
when an <i>h2c</i> connection is established directly (with prior knowledge). when an <i>h2c</i> connection is established directly (with prior knowledge).
+++ +++
|[[http2MaxPoolSize]]`http2MaxPoolSize`|`Number (int)`|
+++
Set the maximum pool size for HTTP/2 connections
+++
|[[http2MaxStreams]]`http2MaxStreams`|`Number (int)`|
+++
Set a client limit of the number concurrent streams for each HTTP/2 connection, this limits the number
of streams the client can create for a connection. The effective number of streams for a
connection is the min of this value and the server's initial settings.
<p/>
Setting the value to <code>-1</code> means to use the value sent by the server's initial settings.
<code>-1</code> is the default value.
+++
|[[idleTimeout]]`idleTimeout`|`Number (int)`| |[[idleTimeout]]`idleTimeout`|`Number (int)`|
+++ +++
Set the idle timeout, in seconds. zero means don't timeout. Set the idle timeout, in seconds. zero means don't timeout.
Expand Down Expand Up @@ -693,16 +706,6 @@ Set the maximum HTTP chunk size
+++ +++
Set the maximum pool size for connections Set the maximum pool size for connections
+++ +++
|[[maxStreams]]`maxStreams`|`Number (int)`|
+++
Set the maximum of concurrent streams for an HTTP/2 connection, this limits the number
of streams the client will create for a connection. The effective number of streams for a
connection can be lower than this value when the server has a lower limit than
this value.
<p/>
Setting the maximum to <code>-1</code> means the client will not limit the concurrency and the client
will use a single connection. <code>-1</code> is the default value.
+++
|[[maxWaitQueueSize]]`maxWaitQueueSize`|`Number (int)`| |[[maxWaitQueueSize]]`maxWaitQueueSize`|`Number (int)`|
+++ +++
Set the maximum requests allowed in the wait queue, any requests beyond the max size will result in Set the maximum requests allowed in the wait queue, any requests beyond the max size will result in
Expand Down
18 changes: 16 additions & 2 deletions src/main/asciidoc/java/http.adoc
Expand Up @@ -60,6 +60,12 @@ upgrade to HTTP/2. It will also accept a direct `h2c` connection beginning with


WARNING: most browsers won't support `h2c`, so for serving web sites you should use `h2` and not `h2c`. WARNING: most browsers won't support `h2c`, so for serving web sites you should use `h2` and not `h2c`.


When a server accepts an HTTP/2 connection, it sends to the client its `link:../../apidocs/io/vertx/core/http/HttpServerOptions.html#getInitialSettings--[initial settings]`.
The settings define how the client can use the connection, the default initial settings for a server are:

- `link:../../apidocs/io/vertx/core/http/Http2Settings.html#getMaxConcurrentStreams--[getMaxConcurrentStreams]`: `100` as recommended by the HTTP/2 RFC
- the default HTTP/2 settings values for the others

=== Logging network server activity === Logging network server activity


For debugging purposes, network activity can be logged. For debugging purposes, network activity can be logged.
Expand Down Expand Up @@ -846,6 +852,9 @@ the same preface from the server.
The http server may not support HTTP/2, the actual version can be checked The http server may not support HTTP/2, the actual version can be checked
with `link:../../apidocs/io/vertx/core/http/HttpClientResponse.html#version--[version]` when the response arrives. with `link:../../apidocs/io/vertx/core/http/HttpClientResponse.html#version--[version]` when the response arrives.


When a clients connects to an HTTP/2 server, it sends to the server its `link:../../apidocs/io/vertx/core/http/HttpClientOptions.html#getInitialSettings--[initial settings]`.
The settings define how the server can use the connection, the default initial settings for a client are the default
values defined by the HTTP/2 RFC.


=== Logging network client activity === Logging network client activity


Expand Down Expand Up @@ -1567,13 +1576,18 @@ When pipe-lining is enabled requests will be written to connections without wait
HTTP/2 advocates to use a single connection to a server, by default the http client uses a single HTTP/2 advocates to use a single connection to a server, by default the http client uses a single
connection for each server, all the streams to the same server are multiplexed on the same connection. connection for each server, all the streams to the same server are multiplexed on the same connection.


When the clients needs to use more than a single connection and use pooling, the `link:../../apidocs/io/vertx/core/http/HttpClientOptions.html#setHttp2MaxPoolSize-int-[setHttp2MaxPoolSize]`
shall be used.

When it is desirable to limit the number of concurrent streams per server and use a connection When it is desirable to limit the number of concurrent streams per server and use a connection
pool instead of a single connection, `link:../../apidocs/io/vertx/core/http/HttpClientOptions.html#setMaxStreams-int-[setMaxStreams]` pool instead of a single connection, `link:../../apidocs/io/vertx/core/http/HttpClientOptions.html#setHttp2MaxStreams-int-[setHttp2MaxStreams]`
can be used. can be used.


[source,java] [source,java]
---- ----
HttpClientOptions clientOptions = new HttpClientOptions().setMaxStreams(10).setMaxPoolSize(3); HttpClientOptions clientOptions = new HttpClientOptions().
setHttp2MaxStreams(10).
setHttp2MaxPoolSize(3);
// Uses up to 3 connections and up to 10 streams per connection // Uses up to 3 connections and up to 10 streams per connection
HttpClient client = vertx.createHttpClient(clientOptions); HttpClient client = vertx.createHttpClient(clientOptions);
Expand Down
Expand Up @@ -44,6 +44,12 @@ public static void fromJson(JsonObject json, HttpClientOptions obj) {
if (json.getValue("h2cUpgrade") instanceof Boolean) { if (json.getValue("h2cUpgrade") instanceof Boolean) {
obj.setH2cUpgrade((Boolean)json.getValue("h2cUpgrade")); obj.setH2cUpgrade((Boolean)json.getValue("h2cUpgrade"));
} }
if (json.getValue("http2MaxPoolSize") instanceof Number) {
obj.setHttp2MaxPoolSize(((Number)json.getValue("http2MaxPoolSize")).intValue());
}
if (json.getValue("http2MaxStreams") instanceof Number) {
obj.setHttp2MaxStreams(((Number)json.getValue("http2MaxStreams")).intValue());
}
if (json.getValue("initialSettings") instanceof JsonObject) { if (json.getValue("initialSettings") instanceof JsonObject) {
obj.setInitialSettings(new io.vertx.core.http.Http2Settings((JsonObject)json.getValue("initialSettings"))); obj.setInitialSettings(new io.vertx.core.http.Http2Settings((JsonObject)json.getValue("initialSettings")));
} }
Expand All @@ -56,9 +62,6 @@ public static void fromJson(JsonObject json, HttpClientOptions obj) {
if (json.getValue("maxPoolSize") instanceof Number) { if (json.getValue("maxPoolSize") instanceof Number) {
obj.setMaxPoolSize(((Number)json.getValue("maxPoolSize")).intValue()); obj.setMaxPoolSize(((Number)json.getValue("maxPoolSize")).intValue());
} }
if (json.getValue("maxStreams") instanceof Number) {
obj.setMaxStreams(((Number)json.getValue("maxStreams")).intValue());
}
if (json.getValue("maxWaitQueueSize") instanceof Number) { if (json.getValue("maxWaitQueueSize") instanceof Number) {
obj.setMaxWaitQueueSize(((Number)json.getValue("maxWaitQueueSize")).intValue()); obj.setMaxWaitQueueSize(((Number)json.getValue("maxWaitQueueSize")).intValue());
} }
Expand Down Expand Up @@ -92,13 +95,14 @@ public static void toJson(HttpClientOptions obj, JsonObject json) {
} }
json.put("defaultPort", obj.getDefaultPort()); json.put("defaultPort", obj.getDefaultPort());
json.put("h2cUpgrade", obj.isH2cUpgrade()); json.put("h2cUpgrade", obj.isH2cUpgrade());
json.put("http2MaxPoolSize", obj.getHttp2MaxPoolSize());
json.put("http2MaxStreams", obj.getHttp2MaxStreams());
if (obj.getInitialSettings() != null) { if (obj.getInitialSettings() != null) {
json.put("initialSettings", obj.getInitialSettings().toJson()); json.put("initialSettings", obj.getInitialSettings().toJson());
} }
json.put("keepAlive", obj.isKeepAlive()); json.put("keepAlive", obj.isKeepAlive());
json.put("maxChunkSize", obj.getMaxChunkSize()); json.put("maxChunkSize", obj.getMaxChunkSize());
json.put("maxPoolSize", obj.getMaxPoolSize()); json.put("maxPoolSize", obj.getMaxPoolSize());
json.put("maxStreams", obj.getMaxStreams());
json.put("maxWaitQueueSize", obj.getMaxWaitQueueSize()); json.put("maxWaitQueueSize", obj.getMaxWaitQueueSize());
json.put("maxWebsocketFrameSize", obj.getMaxWebsocketFrameSize()); json.put("maxWebsocketFrameSize", obj.getMaxWebsocketFrameSize());
json.put("pipelining", obj.isPipelining()); json.put("pipelining", obj.isPipelining());
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/examples/HTTP2Examples.java
Expand Up @@ -284,7 +284,9 @@ public void example28(HttpConnection connection) {


public void useMaxStreams(Vertx vertx) { public void useMaxStreams(Vertx vertx) {


HttpClientOptions clientOptions = new HttpClientOptions().setMaxStreams(10).setMaxPoolSize(3); HttpClientOptions clientOptions = new HttpClientOptions().
setHttp2MaxStreams(10).
setHttp2MaxPoolSize(3);


// Uses up to 3 connections and up to 10 streams per connection // Uses up to 3 connections and up to 10 streams per connection
HttpClient client = vertx.createHttpClient(clientOptions); HttpClient client = vertx.createHttpClient(clientOptions);
Expand Down
66 changes: 48 additions & 18 deletions src/main/java/io/vertx/core/http/HttpClientOptions.java
Expand Up @@ -46,10 +46,15 @@ public class HttpClientOptions extends ClientOptionsBase {
*/ */
public static final int DEFAULT_MAX_POOL_SIZE = 5; public static final int DEFAULT_MAX_POOL_SIZE = 5;


/**
* The default maximum number of connections an HTTP/2 client will pool = 1
*/
public static final int DEFAULT_HTTP2_MAX_POOL_SIZE = 1;

/** /**
* The default maximum number of concurrent stream per connection for HTTP/2 = -1 * The default maximum number of concurrent stream per connection for HTTP/2 = -1
*/ */
public static final int DEFAULT_MAX_STREAMS = -1; public static final int DEFAULT_HTTP2_MAX_STREAMS = -1;


/** /**
* Default value of whether keep-alive is enabled = true * Default value of whether keep-alive is enabled = true
Expand Down Expand Up @@ -115,7 +120,8 @@ public class HttpClientOptions extends ClientOptionsBase {
private int maxPoolSize; private int maxPoolSize;
private boolean keepAlive; private boolean keepAlive;
private boolean pipelining; private boolean pipelining;
private int maxStreams; private int http2MaxPoolSize;
private int http2MaxStreams;


private boolean tryUseCompression; private boolean tryUseCompression;
private int maxWebsocketFrameSize; private int maxWebsocketFrameSize;
Expand Down Expand Up @@ -147,7 +153,8 @@ public HttpClientOptions(HttpClientOptions other) {
this.maxPoolSize = other.getMaxPoolSize(); this.maxPoolSize = other.getMaxPoolSize();
this.keepAlive = other.isKeepAlive(); this.keepAlive = other.isKeepAlive();
this.pipelining = other.isPipelining(); this.pipelining = other.isPipelining();
this.maxStreams = other.maxStreams; this.http2MaxPoolSize = other.getHttp2MaxPoolSize();
this.http2MaxStreams = other.http2MaxStreams;
this.tryUseCompression = other.isTryUseCompression(); this.tryUseCompression = other.isTryUseCompression();
this.maxWebsocketFrameSize = other.maxWebsocketFrameSize; this.maxWebsocketFrameSize = other.maxWebsocketFrameSize;
this.defaultHost = other.defaultHost; this.defaultHost = other.defaultHost;
Expand Down Expand Up @@ -176,7 +183,8 @@ private void init() {
maxPoolSize = DEFAULT_MAX_POOL_SIZE; maxPoolSize = DEFAULT_MAX_POOL_SIZE;
keepAlive = DEFAULT_KEEP_ALIVE; keepAlive = DEFAULT_KEEP_ALIVE;
pipelining = DEFAULT_PIPELINING; pipelining = DEFAULT_PIPELINING;
maxStreams = DEFAULT_MAX_STREAMS; http2MaxStreams = DEFAULT_HTTP2_MAX_STREAMS;
http2MaxPoolSize = DEFAULT_HTTP2_MAX_POOL_SIZE;
tryUseCompression = DEFAULT_TRY_USE_COMPRESSION; tryUseCompression = DEFAULT_TRY_USE_COMPRESSION;
maxWebsocketFrameSize = DEFAULT_MAX_WEBSOCKET_FRAME_SIZE; maxWebsocketFrameSize = DEFAULT_MAX_WEBSOCKET_FRAME_SIZE;
defaultHost = DEFAULT_DEFAULT_HOST; defaultHost = DEFAULT_DEFAULT_HOST;
Expand Down Expand Up @@ -352,26 +360,48 @@ public HttpClientOptions setMaxPoolSize(int maxPoolSize) {


/** /**
* @return the maximum number of concurrent streams for an HTTP/2 connection, {@code -1} means * @return the maximum number of concurrent streams for an HTTP/2 connection, {@code -1} means
* no limit (default value) * the value sent by the server
*/ */
public int getMaxStreams() { public int getHttp2MaxStreams() {
return maxStreams; return http2MaxStreams;
} }


/** /**
* Set the maximum of concurrent streams for an HTTP/2 connection, this limits the number * Set a client limit of the number concurrent streams for each HTTP/2 connection, this limits the number
* of streams the client will create for a connection. The effective number of streams for a * of streams the client can create for a connection. The effective number of streams for a
* connection can be lower than this value when the server has a lower limit than * connection is the min of this value and the server's initial settings.
* this value.
* <p/> * <p/>
* Setting the maximum to {@code -1} means the client will not limit the concurrency and the client * Setting the value to {@code -1} means to use the value sent by the server's initial settings.
* will use a single connection. {@code -1} is the default value. * {@code -1} is the default value.
*
* @param http2MaxStreams the maximum concurrent for an HTTP/2 connection
* @return a reference to this, so the API can be used fluently
*/
public HttpClientOptions setHttp2MaxStreams(int http2MaxStreams) {
this.http2MaxStreams = http2MaxStreams;
return this;
}

/**
* Get the maximum pool size for HTTP/2 connections
* *
* @param maxStreams the maximum concurrent for a connection * @return the maximum pool size
*/
public int getHttp2MaxPoolSize() {
return http2MaxPoolSize;
}

/**
* Set the maximum pool size for HTTP/2 connections
*
* @param max the maximum pool size
* @return a reference to this, so the API can be used fluently * @return a reference to this, so the API can be used fluently
*/ */
public HttpClientOptions setMaxStreams(int maxStreams) { public HttpClientOptions setHttp2MaxPoolSize(int max) {
this.maxStreams = maxStreams; if (maxPoolSize < 1) {
throw new IllegalArgumentException("http2MaxPoolSize must be > 0");
}
this.http2MaxPoolSize = max;
return this; return this;
} }


Expand Down Expand Up @@ -669,7 +699,7 @@ public boolean equals(Object o) {
if (defaultPort != that.defaultPort) return false; if (defaultPort != that.defaultPort) return false;
if (keepAlive != that.keepAlive) return false; if (keepAlive != that.keepAlive) return false;
if (maxPoolSize != that.maxPoolSize) return false; if (maxPoolSize != that.maxPoolSize) return false;
if (maxStreams != that.maxStreams) return false; if (http2MaxStreams != that.http2MaxStreams) return false;
if (maxWebsocketFrameSize != that.maxWebsocketFrameSize) return false; if (maxWebsocketFrameSize != that.maxWebsocketFrameSize) return false;
if (pipelining != that.pipelining) return false; if (pipelining != that.pipelining) return false;
if (tryUseCompression != that.tryUseCompression) return false; if (tryUseCompression != that.tryUseCompression) return false;
Expand All @@ -690,7 +720,7 @@ public int hashCode() {
int result = super.hashCode(); int result = super.hashCode();
result = 31 * result + (verifyHost ? 1 : 0); result = 31 * result + (verifyHost ? 1 : 0);
result = 31 * result + maxPoolSize; result = 31 * result + maxPoolSize;
result = 31 * result + maxStreams; result = 31 * result + http2MaxStreams;
result = 31 * result + (keepAlive ? 1 : 0); result = 31 * result + (keepAlive ? 1 : 0);
result = 31 * result + (pipelining ? 1 : 0); result = 31 * result + (pipelining ? 1 : 0);
result = 31 * result + (tryUseCompression ? 1 : 0); result = 31 * result + (tryUseCompression ? 1 : 0);
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/io/vertx/core/http/HttpServerOptions.java
Expand Up @@ -74,6 +74,11 @@ public class HttpServerOptions extends NetServerOptions {
*/ */
public static final List<HttpVersion> DEFAULT_ALPN_VERSIONS = Collections.unmodifiableList(Arrays.asList(HttpVersion.HTTP_2, HttpVersion.HTTP_1_1)); public static final List<HttpVersion> DEFAULT_ALPN_VERSIONS = Collections.unmodifiableList(Arrays.asList(HttpVersion.HTTP_2, HttpVersion.HTTP_1_1));


/**
* The default inital settings max concurrent stream for an HTTP/2 server = 100
*/
public static final long DEFAULT_INITIAL_SETTINGS_MAX_CONCURRENT_STREAMS = 100;

private boolean compressionSupported; private boolean compressionSupported;
private int maxWebsocketFrameSize; private int maxWebsocketFrameSize;
private String websocketSubProtocols; private String websocketSubProtocols;
Expand Down Expand Up @@ -130,7 +135,7 @@ private void init() {
maxChunkSize = DEFAULT_MAX_CHUNK_SIZE; maxChunkSize = DEFAULT_MAX_CHUNK_SIZE;
maxInitialLineLength = DEFAULT_MAX_INITIAL_LINE_LENGTH; maxInitialLineLength = DEFAULT_MAX_INITIAL_LINE_LENGTH;
maxHeaderSize = DEFAULT_MAX_HEADER_SIZE; maxHeaderSize = DEFAULT_MAX_HEADER_SIZE;
initialSettings = new Http2Settings(); initialSettings = new Http2Settings().setMaxConcurrentStreams(DEFAULT_INITIAL_SETTINGS_MAX_CONCURRENT_STREAMS);
alpnVersions = new ArrayList<>(DEFAULT_ALPN_VERSIONS); alpnVersions = new ArrayList<>(DEFAULT_ALPN_VERSIONS);
} }


Expand Down
31 changes: 18 additions & 13 deletions src/main/java/io/vertx/core/http/impl/ConnectionManager.java
Expand Up @@ -74,7 +74,6 @@ public class ConnectionManager {
private final boolean keepAlive; private final boolean keepAlive;
private final boolean pipelining; private final boolean pipelining;
private final int maxWaitQueueSize; private final int maxWaitQueueSize;
private final int http2MaxSockets;
private final int http2MaxConcurrency; private final int http2MaxConcurrency;
private final boolean logEnabled; private final boolean logEnabled;
private final ChannelConnector connector; private final ChannelConnector connector;
Expand All @@ -88,9 +87,7 @@ public class ConnectionManager {
this.keepAlive = client.getOptions().isKeepAlive(); this.keepAlive = client.getOptions().isKeepAlive();
this.pipelining = client.getOptions().isPipelining(); this.pipelining = client.getOptions().isPipelining();
this.maxWaitQueueSize = client.getOptions().getMaxWaitQueueSize(); this.maxWaitQueueSize = client.getOptions().getMaxWaitQueueSize();
int maxStreams = options.getMaxStreams(); this.http2MaxConcurrency = options.getHttp2MaxStreams() < 1 ? Integer.MAX_VALUE : options.getHttp2MaxStreams();
this.http2MaxSockets = maxStreams < 1 ? 1 : options.getMaxPoolSize();
this.http2MaxConcurrency = maxStreams < 1 ? Integer.MAX_VALUE : maxStreams;
this.logEnabled = client.getOptions().getLogActivity(); this.logEnabled = client.getOptions().getLogActivity();
this.connector = new ChannelConnector(); this.connector = new ChannelConnector();
this.metrics = metrics; this.metrics = metrics;
Expand Down Expand Up @@ -207,11 +204,11 @@ public class ConnQueue {
this.address = address; this.address = address;
this.mgr = mgr; this.mgr = mgr;
if (version == HttpVersion.HTTP_2) { if (version == HttpVersion.HTTP_2) {
maxSize = http2MaxSockets; maxSize = options.getHttp2MaxPoolSize();
pool = (Pool)new Http2Pool(this, client, ConnectionManager.this.metrics, mgr.connectionMap, http2MaxSockets, http2MaxConcurrency, logEnabled); pool = (Pool)new Http2Pool(this, client, ConnectionManager.this.metrics, mgr.connectionMap, http2MaxConcurrency, logEnabled, options.getHttp2MaxPoolSize());
} else { } else {
maxSize = client.getOptions().getMaxPoolSize(); maxSize = options.getMaxPoolSize();
pool = (Pool)new Http1xPool(client, ConnectionManager.this.metrics, options, this, mgr.connectionMap, version); pool = (Pool)new Http1xPool(client, ConnectionManager.this.metrics, options, this, mgr.connectionMap, version, options.getMaxPoolSize());
} }
this.metric = ConnectionManager.this.metrics.createEndpoint(address.host, address.port, maxSize); this.metric = ConnectionManager.this.metrics.createEndpoint(address.host, address.port, maxSize);
} }
Expand All @@ -227,7 +224,10 @@ public synchronized void getConnection(Waiter waiter) {
} }
context.runOnContext(v -> deliverStream(conn, waiter)); context.runOnContext(v -> deliverStream(conn, waiter));
} else { } else {
if (connCount == maxSize) { if (pool.canCreateConnection(connCount)) {
// Create a new connection
createNewConnection(waiter);
} else {
// Wait in queue // Wait in queue
if (maxWaitQueueSize < 0 || waiters.size() < maxWaitQueueSize) { if (maxWaitQueueSize < 0 || waiters.size() < maxWaitQueueSize) {
if (ConnectionManager.this.metrics.isEnabled()) { if (ConnectionManager.this.metrics.isEnabled()) {
Expand All @@ -237,9 +237,6 @@ public synchronized void getConnection(Waiter waiter) {
} else { } else {
waiter.handleFailure(new ConnectionPoolTooBusyException("Connection pool reached max wait queue size of " + maxWaitQueueSize)); waiter.handleFailure(new ConnectionPoolTooBusyException("Connection pool reached max wait queue size of " + maxWaitQueueSize));
} }
} else {
// Create a new connection
createNewConnection(waiter);
} }
} }
} }
Expand Down Expand Up @@ -333,7 +330,7 @@ private void handshakeFailure(ContextImpl context, Channel ch, Throwable cause,
private void fallbackToHttp1x(Channel ch, ContextImpl context, HttpVersion fallbackVersion, int port, String host, Waiter waiter) { private void fallbackToHttp1x(Channel ch, ContextImpl context, HttpVersion fallbackVersion, int port, String host, Waiter waiter) {
// change the pool to Http1xPool // change the pool to Http1xPool
synchronized (this) { synchronized (this) {
pool = (Pool)new Http1xPool(client, ConnectionManager.this.metrics, options, this, mgr.connectionMap, fallbackVersion); pool = (Pool)new Http1xPool(client, ConnectionManager.this.metrics, options, this, mgr.connectionMap, fallbackVersion, options.getMaxPoolSize());
} }
http1xConnected(fallbackVersion, context, port, host, ch, waiter); http1xConnected(fallbackVersion, context, port, host, ch, waiter);
} }
Expand Down Expand Up @@ -381,6 +378,14 @@ interface Pool<C extends HttpClientConnection> {


C pollConnection(); C pollConnection();


/**
* Determine when a new connection should be created
*
* @param connCount the actual connection count including the one being created
* @return true whether or not a new connection can be created
*/
boolean canCreateConnection(int connCount);

void closeAllConnections(); void closeAllConnections();


void recycle(C conn); void recycle(C conn);
Expand Down
10 changes: 9 additions & 1 deletion src/main/java/io/vertx/core/http/impl/Http1xPool.java
Expand Up @@ -45,8 +45,10 @@ public class Http1xPool implements ConnectionManager.Pool<ClientConnection> {
private final HttpVersion version; private final HttpVersion version;
private final Set<ClientConnection> allConnections = new HashSet<>(); private final Set<ClientConnection> allConnections = new HashSet<>();
private final Queue<ClientConnection> availableConnections = new ArrayDeque<>(); private final Queue<ClientConnection> availableConnections = new ArrayDeque<>();
private final int maxSockets;


public Http1xPool(HttpClientImpl client, HttpClientMetrics metrics, HttpClientOptions options, ConnectionManager.ConnQueue queue, Map<Channel, HttpClientConnection> connectionMap, HttpVersion version) { public Http1xPool(HttpClientImpl client, HttpClientMetrics metrics, HttpClientOptions options, ConnectionManager.ConnQueue queue,
Map<Channel, HttpClientConnection> connectionMap, HttpVersion version, int maxSockets) {
this.queue = queue; this.queue = queue;
this.version = version; this.version = version;
this.client = client; this.client = client;
Expand All @@ -55,6 +57,7 @@ public Http1xPool(HttpClientImpl client, HttpClientMetrics metrics, HttpClientOp
this.keepAlive = options.isKeepAlive(); this.keepAlive = options.isKeepAlive();
this.ssl = options.isSsl(); this.ssl = options.isSsl();
this.connectionMap = connectionMap; this.connectionMap = connectionMap;
this.maxSockets = maxSockets;
} }


@Override @Override
Expand All @@ -68,6 +71,11 @@ public ClientConnection pollConnection() {
return availableConnections.poll(); return availableConnections.poll();
} }


@Override
public boolean canCreateConnection(int connCount) {
return connCount < maxSockets;
}

@Override @Override
public HttpClientStream createStream(ClientConnection conn) { public HttpClientStream createStream(ClientConnection conn) {
return conn; return conn;
Expand Down

0 comments on commit 3afe8bb

Please sign in to comment.