in Microsoft.Azure.Cosmos/src/DocumentClient.cs [699:1055]
internal virtual void Initialize(Uri serviceEndpoint,
ConnectionPolicy connectionPolicy = null,
Documents.ConsistencyLevel? desiredConsistencyLevel = null,
HttpMessageHandler handler = null,
ISessionContainer sessionContainer = null,
bool? enableCpuMonitor = null,
IStoreClientFactory storeClientFactory = null,
TokenCredential tokenCredential = null,
string cosmosClientId = null,
RemoteCertificateValidationCallback remoteCertificateValidationCallback = null,
CosmosClientTelemetryOptions cosmosClientTelemetryOptions = null,
bool enableThinClientMode = false)
{
if (serviceEndpoint == null)
{
throw new ArgumentNullException("serviceEndpoint");
}
this.clientId = cosmosClientId;
this.remoteCertificateValidationCallback = remoteCertificateValidationCallback;
this.cosmosClientTelemetryOptions = cosmosClientTelemetryOptions ?? new CosmosClientTelemetryOptions();
this.queryPartitionProvider = new AsyncLazy<QueryPartitionProvider>(async () =>
{
await this.EnsureValidClientAsync(NoOpTrace.Singleton);
return new QueryPartitionProvider(this.accountServiceConfiguration.QueryEngineConfiguration);
}, CancellationToken.None);
#if !(NETSTANDARD15 || NETSTANDARD16)
#if NETSTANDARD20
// GetEntryAssembly returns null when loaded from native netstandard2.0
if (System.Reflection.Assembly.GetEntryAssembly() != null)
{
#endif
// For tests we want to allow stronger consistency during construction or per call
string allowOverrideStrongerConsistencyConfig = System.Configuration.ConfigurationManager.AppSettings[DocumentClient.AllowOverrideStrongerConsistency];
if (!string.IsNullOrEmpty(allowOverrideStrongerConsistencyConfig))
{
if (!bool.TryParse(allowOverrideStrongerConsistencyConfig, out this.allowOverrideStrongerConsistency))
{
this.allowOverrideStrongerConsistency = false;
}
}
// We might want to override the defaults sometime
string maxConcurrentConnectionOpenRequestsOverrideString = System.Configuration.ConfigurationManager.AppSettings[DocumentClient.MaxConcurrentConnectionOpenConfig];
if (!string.IsNullOrEmpty(maxConcurrentConnectionOpenRequestsOverrideString))
{
int maxConcurrentConnectionOpenRequestOverrideInt = 0;
if (Int32.TryParse(maxConcurrentConnectionOpenRequestsOverrideString, out maxConcurrentConnectionOpenRequestOverrideInt))
{
this.maxConcurrentConnectionOpenRequests = maxConcurrentConnectionOpenRequestOverrideInt;
}
}
string openConnectionTimeoutInSecondsOverrideString = System.Configuration.ConfigurationManager.AppSettings[DocumentClient.OpenConnectionTimeoutInSecondsConfig];
if (!string.IsNullOrEmpty(openConnectionTimeoutInSecondsOverrideString))
{
int openConnectionTimeoutInSecondsOverrideInt = 0;
if (Int32.TryParse(openConnectionTimeoutInSecondsOverrideString, out openConnectionTimeoutInSecondsOverrideInt))
{
this.openConnectionTimeoutInSeconds = openConnectionTimeoutInSecondsOverrideInt;
}
}
string idleConnectionTimeoutInSecondsOverrideString = System.Configuration.ConfigurationManager.AppSettings[DocumentClient.IdleConnectionTimeoutInSecondsConfig];
if (!string.IsNullOrEmpty(idleConnectionTimeoutInSecondsOverrideString))
{
int idleConnectionTimeoutInSecondsOverrideInt = 0;
if (Int32.TryParse(idleConnectionTimeoutInSecondsOverrideString, out idleConnectionTimeoutInSecondsOverrideInt))
{
this.idleConnectionTimeoutInSeconds = idleConnectionTimeoutInSecondsOverrideInt;
}
}
string transportTimerPoolGranularityInSecondsOverrideString = System.Configuration.ConfigurationManager.AppSettings[DocumentClient.TransportTimerPoolGranularityInSecondsConfig];
if (!string.IsNullOrEmpty(transportTimerPoolGranularityInSecondsOverrideString))
{
int timerPoolGranularityInSecondsOverrideInt = 0;
if (Int32.TryParse(transportTimerPoolGranularityInSecondsOverrideString, out timerPoolGranularityInSecondsOverrideInt))
{
// timeoutgranularity specified should be greater than min(5 seconds)
if (timerPoolGranularityInSecondsOverrideInt > this.timerPoolGranularityInSeconds)
{
this.timerPoolGranularityInSeconds = timerPoolGranularityInSecondsOverrideInt;
}
}
}
string enableRntbdChannelOverrideString = System.Configuration.ConfigurationManager.AppSettings[DocumentClient.EnableTcpChannelConfig];
if (!string.IsNullOrEmpty(enableRntbdChannelOverrideString))
{
bool enableRntbdChannel = false;
if (bool.TryParse(enableRntbdChannelOverrideString, out enableRntbdChannel))
{
this.enableRntbdChannel = enableRntbdChannel;
}
}
string maxRequestsPerRntbdChannelOverrideString = System.Configuration.ConfigurationManager.AppSettings[DocumentClient.MaxRequestsPerChannelConfig];
if (!string.IsNullOrEmpty(maxRequestsPerRntbdChannelOverrideString))
{
int maxRequestsPerChannel = DocumentClient.DefaultMaxRequestsPerRntbdChannel;
if (int.TryParse(maxRequestsPerRntbdChannelOverrideString, out maxRequestsPerChannel))
{
this.maxRequestsPerRntbdChannel = maxRequestsPerChannel;
}
}
string rntbdPartitionCountOverrideString = System.Configuration.ConfigurationManager.AppSettings[DocumentClient.TcpPartitionCount];
if (!string.IsNullOrEmpty(rntbdPartitionCountOverrideString))
{
int rntbdPartitionCount = DocumentClient.DefaultRntbdPartitionCount;
if (int.TryParse(rntbdPartitionCountOverrideString, out rntbdPartitionCount))
{
this.rntbdPartitionCount = rntbdPartitionCount;
}
}
string maxRntbdChannelsOverrideString = System.Configuration.ConfigurationManager.AppSettings[DocumentClient.MaxChannelsPerHostConfig];
if (!string.IsNullOrEmpty(maxRntbdChannelsOverrideString))
{
int maxRntbdChannels = DefaultMaxRntbdChannelsPerHost;
if (int.TryParse(maxRntbdChannelsOverrideString, out maxRntbdChannels))
{
this.maxRntbdChannels = maxRntbdChannels;
}
}
string rntbdPortReuseModeOverrideString = System.Configuration.ConfigurationManager.AppSettings[DocumentClient.RntbdPortReuseMode];
if (!string.IsNullOrEmpty(rntbdPortReuseModeOverrideString))
{
PortReuseMode portReuseMode = DefaultRntbdPortReuseMode;
if (Enum.TryParse<PortReuseMode>(rntbdPortReuseModeOverrideString, out portReuseMode))
{
this.rntbdPortReuseMode = portReuseMode;
}
}
string rntbdPortPoolReuseThresholdOverrideString = System.Configuration.ConfigurationManager.AppSettings[DocumentClient.RntbdPortPoolReuseThreshold];
if (!string.IsNullOrEmpty(rntbdPortPoolReuseThresholdOverrideString))
{
int rntbdPortPoolReuseThreshold = DocumentClient.DefaultRntbdPortPoolReuseThreshold;
if (int.TryParse(rntbdPortPoolReuseThresholdOverrideString, out rntbdPortPoolReuseThreshold))
{
this.rntbdPortPoolReuseThreshold = rntbdPortPoolReuseThreshold;
}
}
string rntbdPortPoolBindAttemptsOverrideString = System.Configuration.ConfigurationManager.AppSettings[DocumentClient.RntbdPortPoolBindAttempts];
if (!string.IsNullOrEmpty(rntbdPortPoolBindAttemptsOverrideString))
{
int rntbdPortPoolBindAttempts = DocumentClient.DefaultRntbdPortPoolBindAttempts;
if (int.TryParse(rntbdPortPoolBindAttemptsOverrideString, out rntbdPortPoolBindAttempts))
{
this.rntbdPortPoolBindAttempts = rntbdPortPoolBindAttempts;
}
}
string rntbdReceiveHangDetectionTimeSecondsString = System.Configuration.ConfigurationManager.AppSettings[DocumentClient.RntbdReceiveHangDetectionTimeConfig];
if (!string.IsNullOrEmpty(rntbdReceiveHangDetectionTimeSecondsString))
{
int rntbdReceiveHangDetectionTimeSeconds = DefaultRntbdReceiveHangDetectionTimeSeconds;
if (int.TryParse(rntbdReceiveHangDetectionTimeSecondsString, out rntbdReceiveHangDetectionTimeSeconds))
{
this.rntbdReceiveHangDetectionTimeSeconds = rntbdReceiveHangDetectionTimeSeconds;
}
}
string rntbdSendHangDetectionTimeSecondsString = System.Configuration.ConfigurationManager.AppSettings[DocumentClient.RntbdSendHangDetectionTimeConfig];
if (!string.IsNullOrEmpty(rntbdSendHangDetectionTimeSecondsString))
{
int rntbdSendHangDetectionTimeSeconds = DefaultRntbdSendHangDetectionTimeSeconds;
if (int.TryParse(rntbdSendHangDetectionTimeSecondsString, out rntbdSendHangDetectionTimeSeconds))
{
this.rntbdSendHangDetectionTimeSeconds = rntbdSendHangDetectionTimeSeconds;
}
}
if (enableCpuMonitor.HasValue)
{
this.enableCpuMonitor = enableCpuMonitor.Value;
}
else
{
string enableCpuMonitorString = System.Configuration.ConfigurationManager.AppSettings[DocumentClient.EnableCpuMonitorConfig];
if (!string.IsNullOrEmpty(enableCpuMonitorString))
{
bool enableCpuMonitorFlag = DefaultEnableCpuMonitor;
if (bool.TryParse(enableCpuMonitorString, out enableCpuMonitorFlag))
{
this.enableCpuMonitor = enableCpuMonitorFlag;
}
}
}
#if NETSTANDARD20
}
#endif
#endif
string rntbdMaxConcurrentOpeningConnectionCountOverrideString = Environment.GetEnvironmentVariable(RntbdMaxConcurrentOpeningConnectionCountConfig);
if (!string.IsNullOrEmpty(rntbdMaxConcurrentOpeningConnectionCountOverrideString))
{
if (Int32.TryParse(rntbdMaxConcurrentOpeningConnectionCountOverrideString, out int rntbdMaxConcurrentOpeningConnectionCountOverrideInt))
{
if (rntbdMaxConcurrentOpeningConnectionCountOverrideInt <= 0)
{
throw new ArgumentException("RntbdMaxConcurrentOpeningConnectionCountConfig should be larger than 0");
}
this.rntbdMaxConcurrentOpeningConnectionCount = rntbdMaxConcurrentOpeningConnectionCountOverrideInt;
}
}
// ConnectionPolicy always overrides appconfig
if (connectionPolicy != null)
{
if (connectionPolicy.IdleTcpConnectionTimeout.HasValue)
{
this.idleConnectionTimeoutInSeconds = (int)connectionPolicy.IdleTcpConnectionTimeout.Value.TotalSeconds;
}
if (connectionPolicy.OpenTcpConnectionTimeout.HasValue)
{
this.openConnectionTimeoutInSeconds = (int)connectionPolicy.OpenTcpConnectionTimeout.Value.TotalSeconds;
}
if (connectionPolicy.MaxRequestsPerTcpConnection.HasValue)
{
this.maxRequestsPerRntbdChannel = connectionPolicy.MaxRequestsPerTcpConnection.Value;
}
if (connectionPolicy.MaxTcpPartitionCount.HasValue)
{
this.rntbdPartitionCount = connectionPolicy.MaxTcpPartitionCount.Value;
}
if (connectionPolicy.MaxTcpConnectionsPerEndpoint.HasValue)
{
this.maxRntbdChannels = connectionPolicy.MaxTcpConnectionsPerEndpoint.Value;
}
if (connectionPolicy.PortReuseMode.HasValue)
{
this.rntbdPortReuseMode = connectionPolicy.PortReuseMode.Value;
}
}
this.ServiceEndpoint = serviceEndpoint.OriginalString.EndsWith("/", StringComparison.Ordinal) ? serviceEndpoint : new Uri(serviceEndpoint.OriginalString + "/");
this.ConnectionPolicy = connectionPolicy ?? ConnectionPolicy.Default;
#if !NETSTANDARD16
if (ServicePointAccessor.IsSupported)
{
ServicePointAccessor servicePoint = ServicePointAccessor.FindServicePoint(this.ServiceEndpoint);
servicePoint.ConnectionLimit = this.ConnectionPolicy.MaxConnectionLimit;
}
#endif
this.GlobalEndpointManager = new GlobalEndpointManager(this, this.ConnectionPolicy, this.enableAsyncCacheExceptionNoSharing);
this.PartitionKeyRangeLocation = this.ConnectionPolicy.EnablePartitionLevelFailover || this.ConnectionPolicy.EnablePartitionLevelCircuitBreaker
? new GlobalPartitionEndpointManagerCore(
this.GlobalEndpointManager,
this.ConnectionPolicy.EnablePartitionLevelFailover,
this.ConnectionPolicy.EnablePartitionLevelCircuitBreaker)
: GlobalPartitionEndpointManagerNoOp.Instance;
this.httpClient = CosmosHttpClientCore.CreateWithConnectionPolicy(
this.ApiType,
DocumentClientEventSource.Instance,
this.ConnectionPolicy,
handler,
this.sendingRequest,
this.receivedResponse,
this.chaosInterceptor);
// Loading VM Information (non blocking call and initialization won't fail if this call fails)
VmMetadataApiHandler.TryInitialize(this.httpClient);
if (this.cosmosClientTelemetryOptions.IsClientMetricsEnabled)
{
CosmosDbOperationMeter.Initialize(this.cosmosClientTelemetryOptions);
CosmosDbNetworkMeter.Initialize(this.cosmosClientTelemetryOptions);
CosmosDbOperationMeter.AddInstanceCount(this.ServiceEndpoint);
}
// Starting ClientTelemetry Job
this.telemetryToServiceHelper = TelemetryToServiceHelper.CreateAndInitializeClientConfigAndTelemetryJob(this.clientId,
this.ConnectionPolicy,
this.cosmosAuthorization,
this.httpClient,
this.ServiceEndpoint,
this.GlobalEndpointManager,
this.cancellationTokenSource,
this.chaosInterceptor is not null);
if (sessionContainer != null)
{
this.sessionContainer = sessionContainer;
}
else
{
this.sessionContainer = new SessionContainer(this.ServiceEndpoint.Host);
}
this.retryPolicy = new RetryPolicy(
globalEndpointManager: this.GlobalEndpointManager,
connectionPolicy: this.ConnectionPolicy,
partitionKeyRangeLocationCache: this.PartitionKeyRangeLocation);
this.ResetSessionTokenRetryPolicy = this.retryPolicy;
this.desiredConsistencyLevel = desiredConsistencyLevel;
// Setup the proxy to be used based on connection mode.
// For gateway: GatewayProxy.
// For direct: WFStoreProxy [set in OpenAsync()].
this.eventSource = DocumentClientEventSource.Instance;
this.initializeTaskFactory = (_) => TaskHelper.InlineIfPossible<bool>(
() => this.GetInitializationTaskAsync(storeClientFactory: storeClientFactory),
new ResourceThrottleRetryPolicy(
this.ConnectionPolicy.RetryOptions.MaxRetryAttemptsOnThrottledRequests,
this.ConnectionPolicy.RetryOptions.MaxRetryWaitTimeInSeconds));
// Create the task to start the initialize task
// Task will be awaited on in the EnsureValidClientAsync
Task initTask = this.initTaskCache.GetAsync(
key: DocumentClient.DefaultInitTaskKey,
singleValueInitFunc: this.initializeTaskFactory,
forceRefresh: (_) => false);
// ContinueWith on the initialization task is needed for handling the UnobservedTaskException
// if this task throws for some reason. Awaiting inside a constructor is not supported and
// even if we had to await inside GetInitializationTask to catch the exception, that will
// be a blocking call. In such cases, the recommended approach is to "handle" the
// UnobservedTaskException by using ContinueWith method w/ TaskContinuationOptions.OnlyOnFaulted
// and accessing the Exception property on the target task.
#pragma warning disable VSTHRD110 // Observe result of async calls
#pragma warning disable CDX1000 // DontConvertExceptionToObject
initTask.ContinueWith(t => DefaultTrace.TraceWarning("initializeTask failed {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
#pragma warning restore CDX1000 // DontConvertExceptionToObject
#pragma warning restore VSTHRD110 // Observe result of async calls
this.traceId = Interlocked.Increment(ref DocumentClient.idCounter);
DefaultTrace.TraceInformation(string.Format(
CultureInfo.InvariantCulture,
"DocumentClient with id {0} initialized at endpoint: {1} with ConnectionMode: {2}, connection Protocol: {3}, and consistency level: {4}",
this.traceId,
serviceEndpoint.ToString(),
this.ConnectionPolicy.ConnectionMode.ToString(),
this.ConnectionPolicy.ConnectionProtocol.ToString(),
desiredConsistencyLevel != null ? desiredConsistencyLevel.ToString() : "null"));
this.QueryCompatibilityMode = QueryCompatibilityMode.Default;
}