com.datastax.driver.core.PoolingOptions Maven / Gradle / Ivy
Show all versions of scylla-driver-core Show documentation
/*
* Copyright DataStax, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.datastax.driver.core;
import static com.datastax.driver.core.HostDistance.LOCAL;
import static com.datastax.driver.core.HostDistance.REMOTE;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
import java.util.concurrent.Executor;
/**
* Options related to connection pooling.
*
* The driver uses connections in an asynchronous manner, meaning that multiple requests can be
* submitted on the same connection at the same time. Therefore only a relatively small number of
* connections is needed. For each host, the driver uses a connection pool that may have a variable
* size (it will automatically adjust to the current load).
*
*
With {@code ProtocolVersion#V2} or below, there are at most 128 simultaneous requests per
* connection, so the pool defaults to a variable size. You will typically raise the maximum
* capacity by adding more connections with {@link #setMaxConnectionsPerHost(HostDistance, int)}.
*
*
With {@code ProtocolVersion#V3} or above, there are up to 32768 requests per connection, and
* the pool defaults to a fixed size of 1. You will typically raise the maximum capacity by allowing
* more simultaneous requests per connection ({@link #setMaxRequestsPerConnection(HostDistance,
* int)}).
*
*
All parameters can be separately set for {@code LOCAL} and {@code REMOTE} hosts ({@link
* HostDistance}). For {@code IGNORED} hosts, no connections are created so these settings cannot be
* changed.
*/
public class PoolingOptions {
/**
* The value returned for connection options when they have not been set by the client, and the
* protocol version is not known yet.
*
*
Once a {@code PoolingOptions} object is associated to a {@link Cluster} and that cluster
* initializes, the protocol version will be detected, and connection options will take their
* default values for that protocol version.
*
*
The methods that may return this value are: {@link
* #getCoreConnectionsPerHost(HostDistance)}, {@link #getMaxConnectionsPerHost(HostDistance)},
* {@link #getNewConnectionThreshold(HostDistance)}, {@link
* #getMaxRequestsPerConnection(HostDistance)}.
*/
public static final int UNSET = Integer.MIN_VALUE;
public static final String CORE_POOL_LOCAL_KEY = "corePoolLocal";
public static final String MAX_POOL_LOCAL_KEY = "maxPoolLocal";
public static final String CORE_POOL_REMOTE_KEY = "corePoolRemote";
public static final String MAX_POOL_REMOTE_KEY = "maxPoolRemote";
public static final String NEW_CONNECTION_THRESHOLD_LOCAL_KEY = "newConnectionThresholdLocal";
public static final String NEW_CONNECTION_THRESHOLD_REMOTE_KEY = "newConnectionThresholdRemote";
public static final String MAX_REQUESTS_PER_CONNECTION_LOCAL_KEY =
"maxRequestsPerConnectionLocal";
public static final String MAX_REQUESTS_PER_CONNECTION_REMOTE_KEY =
"maxRequestsPerConnectionRemote";
/**
* The default values for connection options, that depend on the native protocol version.
*
*
The map stores protocol versions in ascending order, and only the versions that introduced a
* change are present. To find the defaults for a particular version, look for the highest key
* that is less than or equal to that version, in other words:
*
*
{@code
* ProtocolVersion referenceVersion = null;
* for (ProtocolVersion key : DEFAULTS.keySet()) {
* if (key.compareTo(actualVersion) > 0)
* break;
* else
* referenceVersion = key;
* }
* Map defaults = DEFAULTS.get(referenceVersion);
* }
*
* Once you've extracted the underlying map, use the keys {@code CORE_POOL_LOCAL_KEY}, {@code
* MAX_POOL_LOCAL_KEY}, {@code CORE_POOL_REMOTE_KEY}, {@code MAX_POOL_REMOTE_KEY}, {@code
* NEW_CONNECTION_THRESHOLD_LOCAL_KEY}, {@code NEW_CONNECTION_THRESHOLD_REMOTE_KEY}, {@code
* MAX_REQUESTS_PER_CONNECTION_LOCAL_KEY} and {@code MAX_REQUESTS_PER_CONNECTION_REMOTE_KEY}.
*
* @see #UNSET
*/
public static final Map> DEFAULTS =
ImmutableMap.>of(
ProtocolVersion.V1,
ImmutableMap.builder()
.put(CORE_POOL_LOCAL_KEY, 2)
.put(MAX_POOL_LOCAL_KEY, 8)
.put(CORE_POOL_REMOTE_KEY, 1)
.put(MAX_POOL_REMOTE_KEY, 2)
.put(NEW_CONNECTION_THRESHOLD_LOCAL_KEY, 100)
.put(NEW_CONNECTION_THRESHOLD_REMOTE_KEY, 100)
.put(MAX_REQUESTS_PER_CONNECTION_LOCAL_KEY, 128)
.put(MAX_REQUESTS_PER_CONNECTION_REMOTE_KEY, 128)
.build(),
ProtocolVersion.V3,
ImmutableMap.builder()
.put(CORE_POOL_LOCAL_KEY, 1)
.put(MAX_POOL_LOCAL_KEY, 1)
.put(CORE_POOL_REMOTE_KEY, 1)
.put(MAX_POOL_REMOTE_KEY, 1)
.put(NEW_CONNECTION_THRESHOLD_LOCAL_KEY, 800)
.put(NEW_CONNECTION_THRESHOLD_REMOTE_KEY, 200)
.put(MAX_REQUESTS_PER_CONNECTION_LOCAL_KEY, 1024)
.put(MAX_REQUESTS_PER_CONNECTION_REMOTE_KEY, 256)
.build());
/** The default value for {@link #getIdleTimeoutSeconds()} ({@value}). */
public static final int DEFAULT_IDLE_TIMEOUT_SECONDS = 120;
/** The default value for {@link #getPoolTimeoutMillis()} ({@value}). */
public static final int DEFAULT_POOL_TIMEOUT_MILLIS = 5000;
/** The default value for {@link #getMaxQueueSize()} ({@value}). */
public static final int DEFAULT_MAX_QUEUE_SIZE = 256;
/** The default value for {@link #getHeartbeatIntervalSeconds()} ({@value}). */
public static final int DEFAULT_HEARTBEAT_INTERVAL_SECONDS = 30;
private static final Executor DEFAULT_INITIALIZATION_EXECUTOR =
GuavaCompatibility.INSTANCE.sameThreadExecutor();
private volatile Cluster.Manager manager;
private volatile ProtocolVersion protocolVersion;
// The defaults for these fields depend on the protocol version, which is only known after control
// connection initialization.
// Yet if the user set them before initialization, we want to keep their values. So we use -1 to
// mean "uninitialized".
private final int[] coreConnections = new int[] {UNSET, UNSET, 0};
private final int[] maxConnections = new int[] {UNSET, UNSET, 0};
private final int[] newConnectionThreshold = new int[] {UNSET, UNSET, 0};
private volatile int maxRequestsPerConnectionLocal = UNSET;
private volatile int maxRequestsPerConnectionRemote = UNSET;
private volatile int idleTimeoutSeconds = DEFAULT_IDLE_TIMEOUT_SECONDS;
private volatile int poolTimeoutMillis = DEFAULT_POOL_TIMEOUT_MILLIS;
private volatile int maxQueueSize = DEFAULT_MAX_QUEUE_SIZE;
private volatile int heartbeatIntervalSeconds = DEFAULT_HEARTBEAT_INTERVAL_SECONDS;
private volatile Executor initializationExecutor = DEFAULT_INITIALIZATION_EXECUTOR;
public PoolingOptions() {}
void register(Cluster.Manager manager) {
this.manager = manager;
}
/**
* Returns the core number of connections per host.
*
* @param distance the {@code HostDistance} for which to return this threshold.
* @return the core number of connections per host at distance {@code distance}.
*/
public int getCoreConnectionsPerHost(HostDistance distance) {
return coreConnections[distance.ordinal()];
}
/**
* Sets the core number of connections per host.
*
* For the provided {@code distance}, this corresponds to the number of connections initially
* created and kept open to each host of that distance.
*
*
The default value is:
*
*
* - with {@code ProtocolVersion#V2} or below: 2 for {@code LOCAL} hosts and 1 for {@code
* REMOTE} hosts.
*
- with {@code ProtocolVersion#V3} or above: 1 for all hosts.
*
*
* @param distance the {@code HostDistance} for which to set this threshold.
* @param newCoreConnections the value to set
* @return this {@code PoolingOptions}.
* @throws IllegalArgumentException if {@code distance == HostDistance.IGNORED}, or if {@code
* newCoreConnections} is greater than the maximum value for this distance.
* @see #setConnectionsPerHost(HostDistance, int, int)
*/
public synchronized PoolingOptions setCoreConnectionsPerHost(
HostDistance distance, int newCoreConnections) {
if (distance == HostDistance.IGNORED)
throw new IllegalArgumentException(
"Cannot set core connections per host for " + distance + " hosts");
Preconditions.checkArgument(
newCoreConnections >= 0, "core number of connections must be positive");
if (maxConnections[distance.ordinal()] != UNSET)
checkConnectionsPerHostOrder(
newCoreConnections, maxConnections[distance.ordinal()], distance);
int oldCore = coreConnections[distance.ordinal()];
coreConnections[distance.ordinal()] = newCoreConnections;
if (oldCore < newCoreConnections && manager != null) manager.ensurePoolsSizing();
return this;
}
/**
* Returns the maximum number of connections per host.
*
* @param distance the {@code HostDistance} for which to return this threshold.
* @return the maximum number of connections per host at distance {@code distance}.
*/
public int getMaxConnectionsPerHost(HostDistance distance) {
return maxConnections[distance.ordinal()];
}
/**
* Sets the maximum number of connections per host.
*
* For the provided {@code distance}, this corresponds to the maximum number of connections
* that can be created per host at that distance.
*
*
The default value is:
*
*
* - with {@code ProtocolVersion#V2} or below: 8 for {@code LOCAL} hosts and 2 for {@code
* REMOTE} hosts.
*
- with {@code ProtocolVersion#V3} or above: 1 for all hosts.
*
*
* @param distance the {@code HostDistance} for which to set this threshold.
* @param newMaxConnections the value to set
* @return this {@code PoolingOptions}.
* @throws IllegalArgumentException if {@code distance == HostDistance.IGNORED}, or if {@code
* newMaxConnections} is less than the core value for this distance.
* @see #setConnectionsPerHost(HostDistance, int, int)
*/
public synchronized PoolingOptions setMaxConnectionsPerHost(
HostDistance distance, int newMaxConnections) {
if (distance == HostDistance.IGNORED)
throw new IllegalArgumentException(
"Cannot set max connections per host for " + distance + " hosts");
Preconditions.checkArgument(
newMaxConnections >= 0, "max number of connections must be positive");
if (coreConnections[distance.ordinal()] != UNSET)
checkConnectionsPerHostOrder(
coreConnections[distance.ordinal()], newMaxConnections, distance);
maxConnections[distance.ordinal()] = newMaxConnections;
return this;
}
/**
* Sets the core and maximum number of connections per host in one call.
*
* This is a convenience method that is equivalent to calling {@link
* #setCoreConnectionsPerHost(HostDistance, int)} and {@link
* #setMaxConnectionsPerHost(HostDistance, int)}.
*
* @param distance the {@code HostDistance} for which to set these threshold.
* @param core the core number of connections.
* @param max the max number of connections.
* @return this {@code PoolingOptions}.
* @throws IllegalArgumentException if {@code distance == HostDistance.IGNORED}, or if {@code
* core} > {@code max}.
*/
public synchronized PoolingOptions setConnectionsPerHost(
HostDistance distance, int core, int max) {
if (distance == HostDistance.IGNORED)
throw new IllegalArgumentException(
"Cannot set connections per host for " + distance + " hosts");
Preconditions.checkArgument(core >= 0, "core number of connections must be positive");
Preconditions.checkArgument(max >= 0, "max number of connections must be positive");
checkConnectionsPerHostOrder(core, max, distance);
coreConnections[distance.ordinal()] = core;
maxConnections[distance.ordinal()] = max;
return this;
}
/**
* Returns the threshold that triggers the creation of a new connection to a host.
*
* @param distance the {@code HostDistance} for which to return this threshold.
* @return the configured threshold, or the default one if none have been set.
* @see #setNewConnectionThreshold(HostDistance, int)
*/
public int getNewConnectionThreshold(HostDistance distance) {
return newConnectionThreshold[distance.ordinal()];
}
/**
* Sets the threshold that triggers the creation of a new connection to a host.
*
*
A new connection gets created if:
*
*
* - N connections are open
*
- N < {@link #getMaxConnectionsPerHost(HostDistance)}
*
- the number of active requests is more than (N - 1) * {@link
* #getMaxRequestsPerConnection(HostDistance)} + {@link
* #getNewConnectionThreshold(HostDistance)}
*
*
* In other words, if all but the last connection are full, and the last connection is above this
* threshold.
*
* The default value is:
*
*
* - with {@code ProtocolVersion#V2} or below: 100 for all hosts.
*
- with {@code ProtocolVersion#V3} or above: 800 for {@code LOCAL} hosts and 200 for {@code
* REMOTE} hosts.
*
*
* @param distance the {@code HostDistance} for which to configure this threshold.
* @param newValue the value to set (between 0 and 128).
* @return this {@code PoolingOptions}.
* @throws IllegalArgumentException if {@code distance == HostDistance.IGNORED}, or if {@code
* maxSimultaneousRequests} is not in range, or if {@code newValue} is less than the minimum
* value for this distance.
*/
public synchronized PoolingOptions setNewConnectionThreshold(
HostDistance distance, int newValue) {
if (distance == HostDistance.IGNORED)
throw new IllegalArgumentException(
"Cannot set new connection threshold for " + distance + " hosts");
checkRequestsPerConnectionRange(newValue, "New connection threshold", distance);
newConnectionThreshold[distance.ordinal()] = newValue;
return this;
}
/**
* Returns the maximum number of requests per connection.
*
* @param distance the {@code HostDistance} for which to return this threshold.
* @return the maximum number of requests per connection at distance {@code distance}.
* @see #setMaxRequestsPerConnection(HostDistance, int)
*/
public int getMaxRequestsPerConnection(HostDistance distance) {
switch (distance) {
case LOCAL:
return maxRequestsPerConnectionLocal;
case REMOTE:
return maxRequestsPerConnectionRemote;
default:
return 0;
}
}
/**
* Sets the maximum number of requests per connection.
*
* The default value is:
*
*
* - with {@code ProtocolVersion#V2} or below: 128 for all hosts (there should not be any
* reason to change this).
*
- with {@code ProtocolVersion#V3} or above: 1024 for {@code LOCAL} hosts and 256 for {@code
* REMOTE} hosts. These values were chosen so that the default V2 and V3 configuration
* generate the same load on a Cassandra cluster. Protocol V3 can go much higher (up to
* 32768), so if your number of clients is low, don't hesitate to experiment with higher
* values. If you have more than one connection per host, consider also adjusting {@link
* #setNewConnectionThreshold(HostDistance, int)}.
*
*
* @param distance the {@code HostDistance} for which to set this threshold.
* @param newMaxRequests the value to set.
* @return this {@code PoolingOptions}.
* @throws IllegalArgumentException if {@code distance == HostDistance.IGNORED}, or if {@code
* newMaxConnections} is not within the allowed range.
*/
public PoolingOptions setMaxRequestsPerConnection(HostDistance distance, int newMaxRequests) {
checkRequestsPerConnectionRange(newMaxRequests, "Max requests per connection", distance);
switch (distance) {
case LOCAL:
maxRequestsPerConnectionLocal = newMaxRequests;
break;
case REMOTE:
maxRequestsPerConnectionRemote = newMaxRequests;
break;
default:
throw new IllegalArgumentException(
"Cannot set max requests per host for " + distance + " hosts");
}
return this;
}
/**
* Returns the timeout before an idle connection is removed.
*
* @return the timeout.
*/
public int getIdleTimeoutSeconds() {
return idleTimeoutSeconds;
}
/**
* Sets the timeout before an idle connection is removed.
*
* The order of magnitude should be a few minutes (the default is 120 seconds). The timeout
* that triggers the removal has a granularity of 10 seconds.
*
* @param idleTimeoutSeconds the new timeout in seconds.
* @return this {@code PoolingOptions}.
* @throws IllegalArgumentException if the timeout is negative.
*/
public PoolingOptions setIdleTimeoutSeconds(int idleTimeoutSeconds) {
if (idleTimeoutSeconds < 0) throw new IllegalArgumentException("Idle timeout must be positive");
this.idleTimeoutSeconds = idleTimeoutSeconds;
return this;
}
/**
* Returns the timeout when trying to acquire a connection from a host's pool.
*
* @return the timeout.
*/
public int getPoolTimeoutMillis() {
return poolTimeoutMillis;
}
/**
* Sets the timeout when trying to acquire a connection from a host's pool.
*
*
This option works in concert with {@link #setMaxQueueSize(int)} to determine what happens if
* the driver tries to borrow a connection from the pool but none is available:
*
*
* - if either option is set to zero, the attempt is rejected immediately;
*
- else if more than {@code maxQueueSize} requests are already waiting for a connection, the
* attempt is also rejected;
*
- otherwise, the attempt is enqueued; if a connection becomes available before {@code
* poolTimeoutMillis} has elapsed, then the attempt succeeds, otherwise it is rejected.
*
*
* If the attempt is rejected, the driver will move to the next host in the {@link
* com.datastax.driver.core.policies.LoadBalancingPolicy#newQueryPlan(String, Statement)} query
* plan}.
*
* The default is 5 seconds. If this option is set to zero, the driver won't wait at all.
*
* @param poolTimeoutMillis the new value in milliseconds.
* @return this {@code PoolingOptions}
* @throws IllegalArgumentException if the timeout is negative.
*/
public PoolingOptions setPoolTimeoutMillis(int poolTimeoutMillis) {
if (poolTimeoutMillis < 0) throw new IllegalArgumentException("Pool timeout must be positive");
this.poolTimeoutMillis = poolTimeoutMillis;
return this;
}
/**
* Returns the maximum number of requests that get enqueued if no connection is available.
*
* @return the maximum queue size.
*/
public int getMaxQueueSize() {
return maxQueueSize;
}
/**
* Sets the maximum number of requests that get enqueued if no connection is available.
*
*
This option works in concert with {@link #setPoolTimeoutMillis(int)} to determine what
* happens if the driver tries to borrow a connection from the pool but none is available:
*
*
* - if either options is set to zero, the attempt is rejected immediately;
*
- else if more than {@code maxQueueSize} requests are already waiting for a connection, the
* attempt is also rejected;
*
- otherwise, the attempt is enqueued; if a connection becomes available before {@code
* poolTimeoutMillis} has elapsed, then the attempt succeeds, otherwise it is rejected.
*
*
* If the attempt is rejected, the driver will move to the next host in the {@link
* com.datastax.driver.core.policies.LoadBalancingPolicy#newQueryPlan(String, Statement)} query
* plan}.
*
* The default value is {@value DEFAULT_MAX_QUEUE_SIZE}. If this option is set to zero, the
* driver will never enqueue requests.
*
* @param maxQueueSize the new value.
* @return this {@code PoolingOptions}
* @throws IllegalArgumentException if the value is negative.
*/
public PoolingOptions setMaxQueueSize(int maxQueueSize) {
if (maxQueueSize < 0) throw new IllegalArgumentException("Max queue size must be positive");
this.maxQueueSize = maxQueueSize;
return this;
}
/**
* Returns the heart beat interval, after which a message is sent on an idle connection to make
* sure it's still alive.
*
* @return the interval.
*/
public int getHeartbeatIntervalSeconds() {
return heartbeatIntervalSeconds;
}
/**
* Sets the heart beat interval, after which a message is sent on an idle connection to make sure
* it's still alive.
*
*
This is an application-level keep-alive, provided for convenience since adjusting the TCP
* keep-alive might not be practical in all environments.
*
*
This option should be set higher than {@link SocketOptions#getReadTimeoutMillis()}.
*
*
The default value for this option is 30 seconds.
*
* @param heartbeatIntervalSeconds the new value in seconds. If set to 0, it will disable the
* feature.
* @return this {@code PoolingOptions}
* @throws IllegalArgumentException if the interval is negative.
*/
public PoolingOptions setHeartbeatIntervalSeconds(int heartbeatIntervalSeconds) {
if (heartbeatIntervalSeconds < 0)
throw new IllegalArgumentException("Heartbeat interval must be positive");
this.heartbeatIntervalSeconds = heartbeatIntervalSeconds;
return this;
}
/**
* Returns the executor to use for connection initialization.
*
* @return the executor.
* @see #setInitializationExecutor(java.util.concurrent.Executor)
*/
public Executor getInitializationExecutor() {
return initializationExecutor;
}
/**
* Sets the executor to use for connection initialization.
*
*
Connections are open in a completely asynchronous manner. Since initializing the transport
* requires separate CQL queries, the futures representing the completion of these queries are
* transformed and chained. This executor is where these transformations happen.
*
*
This is an advanced option, which should be rarely needed in practice. It defaults to
* Guava's {@code MoreExecutors.sameThreadExecutor()}, which results in running the
* transformations on the network I/O threads; this is fine if the transformations are fast and
* not I/O bound (which is the case by default). One reason why you might want to provide a custom
* executor is if you use authentication with a custom {@link
* com.datastax.driver.core.Authenticator} implementation that performs blocking calls.
*
* @param initializationExecutor the executor to use
* @return this {@code PoolingOptions}
* @throws java.lang.NullPointerException if the executor is null
*/
public PoolingOptions setInitializationExecutor(Executor initializationExecutor) {
Preconditions.checkNotNull(initializationExecutor);
this.initializationExecutor = initializationExecutor;
return this;
}
synchronized void setProtocolVersion(ProtocolVersion actualVersion) {
this.protocolVersion = actualVersion;
ProtocolVersion referenceVersion = null;
for (ProtocolVersion key : DEFAULTS.keySet()) {
if (key.compareTo(actualVersion) > 0) break;
else referenceVersion = key;
}
assert referenceVersion != null; // will not happen since V1 is a key
Map defaults = DEFAULTS.get(referenceVersion);
if (coreConnections[LOCAL.ordinal()] == UNSET)
coreConnections[LOCAL.ordinal()] = defaults.get(CORE_POOL_LOCAL_KEY);
if (maxConnections[LOCAL.ordinal()] == UNSET)
maxConnections[LOCAL.ordinal()] = defaults.get(MAX_POOL_LOCAL_KEY);
checkConnectionsPerHostOrder(
coreConnections[LOCAL.ordinal()], maxConnections[LOCAL.ordinal()], LOCAL);
if (coreConnections[REMOTE.ordinal()] == UNSET)
coreConnections[REMOTE.ordinal()] = defaults.get(CORE_POOL_REMOTE_KEY);
if (maxConnections[REMOTE.ordinal()] == UNSET)
maxConnections[REMOTE.ordinal()] = defaults.get(MAX_POOL_REMOTE_KEY);
checkConnectionsPerHostOrder(
coreConnections[REMOTE.ordinal()], maxConnections[REMOTE.ordinal()], REMOTE);
if (newConnectionThreshold[LOCAL.ordinal()] == UNSET)
newConnectionThreshold[LOCAL.ordinal()] = defaults.get(NEW_CONNECTION_THRESHOLD_LOCAL_KEY);
checkRequestsPerConnectionRange(
newConnectionThreshold[LOCAL.ordinal()], "New connection threshold", LOCAL);
if (newConnectionThreshold[REMOTE.ordinal()] == UNSET)
newConnectionThreshold[REMOTE.ordinal()] = defaults.get(NEW_CONNECTION_THRESHOLD_REMOTE_KEY);
checkRequestsPerConnectionRange(
newConnectionThreshold[REMOTE.ordinal()], "New connection threshold", REMOTE);
if (maxRequestsPerConnectionLocal == UNSET)
maxRequestsPerConnectionLocal = defaults.get(MAX_REQUESTS_PER_CONNECTION_LOCAL_KEY);
checkRequestsPerConnectionRange(
maxRequestsPerConnectionLocal, "Max requests per connection", LOCAL);
if (maxRequestsPerConnectionRemote == UNSET)
maxRequestsPerConnectionRemote = defaults.get(MAX_REQUESTS_PER_CONNECTION_REMOTE_KEY);
checkRequestsPerConnectionRange(
maxRequestsPerConnectionRemote, "Max requests per connection", REMOTE);
}
/**
* Requests the driver to re-evaluate the {@link HostDistance} (through the configured {@link
* com.datastax.driver.core.policies.LoadBalancingPolicy#distance}) for every known hosts and to
* drop/add connections to each hosts according to the computed distance.
*
* Note that, due to backward compatibility issues, this method is not interruptible. If the
* caller thread gets interrupted, the method will complete and only then re-interrupt the thread
* (which you can check with {@code Thread.currentThread().isInterrupted()}).
*/
public void refreshConnectedHosts() {
manager.refreshConnectedHosts();
}
/**
* Requests the driver to re-evaluate the {@link HostDistance} for a given node.
*
* @param host the host to refresh.
* @see #refreshConnectedHosts()
*/
public void refreshConnectedHost(Host host) {
manager.refreshConnectedHost(host);
}
private void checkRequestsPerConnectionRange(
int value, String description, HostDistance distance) {
// If we don't know the protocol version yet, use the highest possible upper bound, this will
// get checked again when possible
int max =
(protocolVersion == null || protocolVersion.compareTo(ProtocolVersion.V3) >= 0)
? StreamIdGenerator.MAX_STREAM_PER_CONNECTION_V3
: StreamIdGenerator.MAX_STREAM_PER_CONNECTION_V2;
if (value < 0 || value > max)
throw new IllegalArgumentException(
String.format(
"%s for %s hosts must be in the range (0, %d)", description, distance, max));
}
private static void checkConnectionsPerHostOrder(int core, int max, HostDistance distance) {
if (core > max)
throw new IllegalArgumentException(
String.format(
"Core connections for %s hosts must be less than max (%d > %d)",
distance, core, max));
}
}