com.azure.cosmos.DirectConnectionConfig Maven / Gradle / Ivy
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package com.azure.cosmos;
import com.azure.cosmos.implementation.Configs;
import com.azure.cosmos.implementation.ImplementationBridgeHelpers;
import io.netty.channel.ChannelOption;
import java.time.Duration;
import static com.azure.cosmos.implementation.guava25.base.Preconditions.checkArgument;
import static com.azure.cosmos.implementation.guava25.base.Preconditions.checkNotNull;
/**
* Represents the connection config with {@link ConnectionMode#DIRECT} associated with Cosmos Client in the Azure Cosmos DB database service.
* For performance tips on how to optimize Direct connection configuration,
* refer to performance tips guide:
* Performance tips guide
*/
public final class DirectConnectionConfig {
// Constants
private static final Boolean DEFAULT_CONNECTION_ENDPOINT_REDISCOVERY_ENABLED = true;
private static final Duration DEFAULT_IDLE_ENDPOINT_TIMEOUT = Duration.ofHours(1l);
private static final Duration DEFAULT_CONNECT_TIMEOUT = Duration.ofSeconds(5L);
private static final Duration DEFAULT_NETWORK_REQUEST_TIMEOUT = Duration.ofSeconds(5L);
private static final Duration MIN_NETWORK_REQUEST_TIMEOUT = Duration.ofSeconds(1L);
private static final Duration MAX_NETWORK_REQUEST_TIMEOUT = Duration.ofSeconds(10L);
private static final int DEFAULT_MAX_CONNECTIONS_PER_ENDPOINT = 130;
private static final int DEFAULT_MAX_REQUESTS_PER_CONNECTION = 30;
private static final int DEFAULT_IO_THREAD_COUNT_PER_CORE_FACTOR = 2;
private static final int DEFAULT_IO_THREAD_PRIORITY = Thread.NORM_PRIORITY;
private boolean connectionEndpointRediscoveryEnabled;
private Duration connectTimeout;
private Duration idleConnectionTimeout;
private Duration idleEndpointTimeout;
private Duration networkRequestTimeout;
private int maxConnectionsPerEndpoint;
private int maxRequestsPerConnection;
private int ioThreadCountPerCoreFactor;
private int ioThreadPriority;
private boolean healthCheckTimeoutDetectionEnabled;
private int minConnectionPoolSizePerEndpoint;
/**
* Constructor
*/
public DirectConnectionConfig() {
this.connectionEndpointRediscoveryEnabled = DEFAULT_CONNECTION_ENDPOINT_REDISCOVERY_ENABLED;
this.connectTimeout = DEFAULT_CONNECT_TIMEOUT;
this.idleConnectionTimeout = Duration.ZERO;
this.idleEndpointTimeout = DEFAULT_IDLE_ENDPOINT_TIMEOUT;
this.maxConnectionsPerEndpoint = DEFAULT_MAX_CONNECTIONS_PER_ENDPOINT;
this.maxRequestsPerConnection = DEFAULT_MAX_REQUESTS_PER_CONNECTION;
this.networkRequestTimeout = DEFAULT_NETWORK_REQUEST_TIMEOUT;
this.ioThreadCountPerCoreFactor = DEFAULT_IO_THREAD_COUNT_PER_CORE_FACTOR;
this.ioThreadPriority = DEFAULT_IO_THREAD_PRIORITY;
this.healthCheckTimeoutDetectionEnabled = Configs.isTcpHealthCheckTimeoutDetectionEnabled();
this.minConnectionPoolSizePerEndpoint = Configs.getMinConnectionPoolSizePerEndpoint();
}
/**
* Gets a value indicating whether Direct TCP connection endpoint rediscovery is enabled.
*
* The connection endpoint rediscovery feature is designed to reduce and spread-out latency spikes that may occur during maintenance operations.
*
* By default, connection endpoint rediscovery is enabled.
*
* @return {@code true} if Direct TCP connection endpoint rediscovery is enabled; {@code false} otherwise.
*/
public boolean isConnectionEndpointRediscoveryEnabled() {
return this.connectionEndpointRediscoveryEnabled;
}
/**
* Sets a value indicating whether Direct TCP connection endpoint rediscovery should be enabled.
*
* The connection endpoint rediscovery feature is designed to reduce and spread-out latency spikes that may occur during maintenance operations.
*
* By default, connection endpoint rediscovery is enabled.
*
* @param connectionEndpointRediscoveryEnabled {@code true} if connection endpoint rediscovery is enabled; {@code
* false} otherwise.
*
* @return the {@linkplain DirectConnectionConfig}.
*/
public DirectConnectionConfig setConnectionEndpointRediscoveryEnabled(boolean connectionEndpointRediscoveryEnabled) {
this.connectionEndpointRediscoveryEnabled = connectionEndpointRediscoveryEnabled;
return this;
}
/**
* Gets the default DIRECT connection configuration.
*
* @return the default direct connection configuration.
*/
public static DirectConnectionConfig getDefaultConfig() {
return new DirectConnectionConfig();
}
/**
* Gets the connect timeout for direct client,
* represents timeout for establishing connections with an endpoint.
*
* Configures timeout for underlying Netty Channel {@link ChannelOption#CONNECT_TIMEOUT_MILLIS}
*
* By default, the connect timeout is 5 seconds.
*
* @return direct connect timeout
*/
public Duration getConnectTimeout() {
return connectTimeout;
}
/**
* Sets the connect timeout for direct client,
* represents timeout for establishing connections with an endpoint.
*
* Configures timeout for underlying Netty Channel {@link ChannelOption#CONNECT_TIMEOUT_MILLIS}
*
* By default, the connect timeout is 5 seconds.
*
* @param connectTimeout the connection timeout
* @return the {@link DirectConnectionConfig}
*/
public DirectConnectionConfig setConnectTimeout(Duration connectTimeout) {
this.connectTimeout = connectTimeout;
return this;
}
/**
* Gets the idle connection timeout for direct client
*
* Default value is {@link Duration#ZERO}
*
* Direct client doesn't close a single connection to an endpoint
* by default unless specified.
*
* @return idle connection timeout
*/
public Duration getIdleConnectionTimeout() {
return idleConnectionTimeout;
}
/**
* Sets the idle connection timeout
*
* Default value is {@link Duration#ZERO}
*
* Direct client doesn't close a single connection to an endpoint
* by default unless specified.
*
* @param idleConnectionTimeout idle connection timeout
* @return the {@link DirectConnectionConfig}
*/
public DirectConnectionConfig setIdleConnectionTimeout(Duration idleConnectionTimeout) {
this.idleConnectionTimeout = idleConnectionTimeout;
return this;
}
/**
* Gets the idle endpoint timeout
*
* Default value is 1 hour.
* If set to {@link Duration#ZERO}, idle endpoint check will be disabled.
*
* If there are no requests to a specific endpoint for idle endpoint timeout duration,
* direct client closes all connections to that endpoint to save resources and I/O cost.
*
* @return the idle endpoint timeout
*/
public Duration getIdleEndpointTimeout() {
return idleEndpointTimeout;
}
/**
* Sets the idle endpoint timeout
*
* Default value is 1 hour.
* If set to {@link Duration#ZERO}, idle endpoint check will be disabled.
*
* If there are no requests to a specific endpoint for idle endpoint timeout duration,
* direct client closes all connections to that endpoint to save resources and I/O cost.
*
* @param idleEndpointTimeout the idle endpoint timeout
* @return the {@link DirectConnectionConfig}
*/
public DirectConnectionConfig setIdleEndpointTimeout(Duration idleEndpointTimeout) {
checkArgument(!idleEndpointTimeout.isNegative(), "IdleEndpointTimeout cannot be less than 0");
this.idleEndpointTimeout = idleEndpointTimeout;
return this;
}
/**
* Gets the max connections per endpoint
* This represents the size of connection pool for a specific endpoint
*
* Default value is 130
*
* @return the max connections per endpoint
*/
public int getMaxConnectionsPerEndpoint() {
return maxConnectionsPerEndpoint;
}
/**
* Sets the max connections per endpoint
* This represents the size of connection pool for a specific endpoint
*
* Default value is 130
*
* @param maxConnectionsPerEndpoint the max connections per endpoint
* @return the {@link DirectConnectionConfig}
*/
public DirectConnectionConfig setMaxConnectionsPerEndpoint(int maxConnectionsPerEndpoint) {
this.maxConnectionsPerEndpoint = maxConnectionsPerEndpoint;
return this;
}
/**
* Gets the max requests per connection
* This represents the number of requests that will be queued
* on a single connection for a specific endpoint
*
* Default value is 30
*
* @return the max requests per endpoint
*/
public int getMaxRequestsPerConnection() {
return maxRequestsPerConnection;
}
/**
* Sets the max requests per connection
* This represents the number of requests that will be queued
* on a single connection for a specific endpoint
*
* Default value is 30
*
* @param maxRequestsPerConnection the max requests per endpoint
* @return the {@link DirectConnectionConfig}
*/
public DirectConnectionConfig setMaxRequestsPerConnection(int maxRequestsPerConnection) {
this.maxRequestsPerConnection = maxRequestsPerConnection;
return this;
}
/**
* Gets the network request timeout interval (time to wait for response from network peer).
*
* Default value is 5 seconds
*
* @return the network request timeout interval
*/
public Duration getNetworkRequestTimeout() {
return networkRequestTimeout;
}
/**
* Sets the network request timeout interval (time to wait for response from network peer).
*
* Default value is 5 seconds.
* It only allows values ≥1s and ≤10s. (backend allows requests to take up-to 5 seconds processing time - 5 seconds
* buffer so 10 seconds in total for transport is more than sufficient).
*
* Attention! Please adjust this value with caution.
* This config represents the max time allowed to wait for and consume a service response after the request has been written to the network connection.
* Setting a value too low can result in having not enough time to wait for the service response - which could cause too aggressive retries and degrade performance.
* Setting a value too high can result in fewer retries and reduce chances of success by retries.
*
* @param networkRequestTimeout the network request timeout interval.
* @return the {@link DirectConnectionConfig}
*/
public DirectConnectionConfig setNetworkRequestTimeout(Duration networkRequestTimeout) {
checkNotNull(networkRequestTimeout, "NetworkRequestTimeout can not be null");
checkArgument(networkRequestTimeout.toMillis() >= MIN_NETWORK_REQUEST_TIMEOUT.toMillis(),
"NetworkRequestTimeout can not be less than %s Millis", MIN_NETWORK_REQUEST_TIMEOUT.toMillis());
checkArgument(networkRequestTimeout.toMillis() <= MAX_NETWORK_REQUEST_TIMEOUT.toMillis(),
"NetworkRequestTimeout can not be larger than %s Millis", MAX_NETWORK_REQUEST_TIMEOUT.toMillis());
this.networkRequestTimeout = networkRequestTimeout;
return this;
}
int getIoThreadCountPerCoreFactor() {
return ioThreadCountPerCoreFactor;
}
DirectConnectionConfig setIoThreadCountPerCoreFactor(int ioThreadCountPerCoreFactor) {
this.ioThreadCountPerCoreFactor = ioThreadCountPerCoreFactor;
return this;
}
int getIoThreadPriority() {
return ioThreadPriority;
}
DirectConnectionConfig setIoThreadPriority(int ioThreadPriority) {
this.ioThreadPriority = ioThreadPriority;
return this;
}
DirectConnectionConfig setHealthCheckTimeoutDetectionEnabled(boolean timeoutDetectionEnabled) {
this.healthCheckTimeoutDetectionEnabled = timeoutDetectionEnabled;
return this;
}
boolean isHealthCheckTimeoutDetectionEnabled() {
return this.healthCheckTimeoutDetectionEnabled;
}
DirectConnectionConfig setMinConnectionPoolSizePerEndpoint(int minConnectionPoolSizePerEndpoint) {
this.minConnectionPoolSizePerEndpoint = minConnectionPoolSizePerEndpoint;
return this;
}
int getMinConnectionPoolSizePerEndpoint() {
return this.minConnectionPoolSizePerEndpoint;
}
@Override
public String toString() {
return "DirectConnectionConfig{" +
"connectTimeout=" + connectTimeout +
", idleConnectionTimeout=" + idleConnectionTimeout +
", idleEndpointTimeout=" + idleEndpointTimeout +
", maxConnectionsPerEndpoint=" + maxConnectionsPerEndpoint +
", maxRequestsPerConnection=" + maxRequestsPerConnection +
", networkRequestTimeout=" + networkRequestTimeout +
", ioThreadCountPerCoreFactor=" + ioThreadCountPerCoreFactor +
", ioThreadPriority=" + ioThreadPriority +
", tcpHealthCheckTimeoutDetectionEnabled=" + healthCheckTimeoutDetectionEnabled +
'}';
}
///////////////////////////////////////////////////////////////////////////////////////////
// the following helper/accessor only helps to access this class outside of this package.//
///////////////////////////////////////////////////////////////////////////////////////////
static void initialize() {
ImplementationBridgeHelpers.DirectConnectionConfigHelper.setDirectConnectionConfigAccessor(
new ImplementationBridgeHelpers.DirectConnectionConfigHelper.DirectConnectionConfigAccessor() {
@Override
public int getIoThreadCountPerCoreFactor(DirectConnectionConfig config) {
return config.getIoThreadCountPerCoreFactor();
}
@Override
public DirectConnectionConfig setIoThreadCountPerCoreFactor(DirectConnectionConfig config,
int ioThreadCountPerCoreFactor) {
return config.setIoThreadCountPerCoreFactor(ioThreadCountPerCoreFactor);
}
@Override
public int getIoThreadPriority(DirectConnectionConfig config) {
return config.getIoThreadPriority();
}
@Override
public DirectConnectionConfig setIoThreadPriority(DirectConnectionConfig config,
int ioThreadPriority) {
return config.setIoThreadPriority(ioThreadPriority);
}
@Override
public DirectConnectionConfig setHealthCheckTimeoutDetectionEnabled(
DirectConnectionConfig directConnectionConfig, boolean timeoutDetectionEnabled) {
directConnectionConfig.setHealthCheckTimeoutDetectionEnabled(timeoutDetectionEnabled);
return directConnectionConfig;
}
@Override
public boolean isHealthCheckTimeoutDetectionEnabled(DirectConnectionConfig directConnectionConfig) {
return directConnectionConfig.isHealthCheckTimeoutDetectionEnabled();
}
@Override
public DirectConnectionConfig setMinConnectionPoolSizePerEndpoint(DirectConnectionConfig directConnectionConfig, int minConnectionPoolSizePerEndpoint) {
directConnectionConfig.setMinConnectionPoolSizePerEndpoint(minConnectionPoolSizePerEndpoint);
return directConnectionConfig;
}
@Override
public int getMinConnectionPoolSizePerEndpoint(DirectConnectionConfig directConnectionConfig) {
return directConnectionConfig.getMinConnectionPoolSizePerEndpoint();
}
});
}
static { initialize(); }
}