Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Internal] Thin Client Integration: Adds thinclient mode and performance tests. #4926

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
60 changes: 58 additions & 2 deletions Microsoft.Azure.Cosmos/src/DocumentClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ internal partial class DocumentClient : IDisposable, IAuthorizationTokenProvider
private readonly bool IsLocalQuorumConsistency = false;
private readonly bool isReplicaAddressValidationEnabled;

// Thin Client
private readonly bool isLiteClientEnabled;
private readonly string liteClientEndpoint;

//Fault Injection
private readonly IChaosInterceptorFactory chaosInterceptorFactory;
private readonly IChaosInterceptor chaosInterceptor;
Expand Down Expand Up @@ -163,6 +167,8 @@ internal partial class DocumentClient : IDisposable, IAuthorizationTokenProvider
private IStoreClientFactory storeClientFactory;
internal CosmosHttpClient httpClient { get; private set; }

internal CosmosHttpClient liteModeHttpClient { get; private set; }

// Flag that indicates whether store client factory must be disposed whenever client is disposed.
// Setting this flag to false will result in store client factory not being disposed when client is disposed.
// This flag is used to allow shared store client factory survive disposition of a document client while other clients continue using it.
Expand Down Expand Up @@ -194,6 +200,7 @@ internal partial class DocumentClient : IDisposable, IAuthorizationTokenProvider
private event EventHandler<SendingRequestEventArgs> sendingRequest;
private event EventHandler<ReceivedResponseEventArgs> receivedResponse;
private Func<TransportClient, TransportClient> transportClientHandlerFactory;
private string liteClientTestEndpoint = "https://cdb-ms-stage-eastus2-fe2.eastus2.cloudapp.azure.com:10650";

/// <summary>
/// Initializes a new instance of the <see cref="DocumentClient"/> class using the
Expand Down Expand Up @@ -241,6 +248,12 @@ public DocumentClient(Uri serviceEndpoint,
this.Initialize(serviceEndpoint, connectionPolicy, desiredConsistencyLevel);
this.initTaskCache = new AsyncCacheNonBlocking<string, bool>(cancellationToken: this.cancellationTokenSource.Token);
this.isReplicaAddressValidationEnabled = ConfigurationManager.IsReplicaAddressValidationEnabled(connectionPolicy);
this.isLiteClientEnabled = ConfigurationManager.IsLiteClientEnabled(defaultValue: true);

if (this.isLiteClientEnabled)
{
this.liteClientEndpoint = ConfigurationManager.GetLiteClientEndpoint(defaultValue: this.liteClientTestEndpoint);
}
}

/// <summary>
Expand Down Expand Up @@ -493,6 +506,12 @@ internal DocumentClient(Uri serviceEndpoint,
this.initTaskCache = new AsyncCacheNonBlocking<string, bool>(cancellationToken: this.cancellationTokenSource.Token);
this.chaosInterceptorFactory = chaosInterceptorFactory;
this.chaosInterceptor = chaosInterceptorFactory?.CreateInterceptor(this);
this.isLiteClientEnabled = ConfigurationManager.IsLiteClientEnabled(defaultValue: true);

if (this.isLiteClientEnabled)
{
this.liteClientEndpoint = ConfigurationManager.GetLiteClientEndpoint(defaultValue: this.liteClientTestEndpoint);
}

this.Initialize(
serviceEndpoint: serviceEndpoint,
Expand All @@ -504,7 +523,8 @@ internal DocumentClient(Uri serviceEndpoint,
storeClientFactory: storeClientFactory,
cosmosClientId: cosmosClientId,
remoteCertificateValidationCallback: remoteCertificateValidationCallback,
cosmosClientTelemetryOptions: cosmosClientTelemetryOptions);
cosmosClientTelemetryOptions: cosmosClientTelemetryOptions,
enableLiteClientMode: this.isLiteClientEnabled);
}

/// <summary>
Expand Down Expand Up @@ -688,7 +708,8 @@ internal virtual void Initialize(Uri serviceEndpoint,
TokenCredential tokenCredential = null,
string cosmosClientId = null,
RemoteCertificateValidationCallback remoteCertificateValidationCallback = null,
CosmosClientTelemetryOptions cosmosClientTelemetryOptions = null)
CosmosClientTelemetryOptions cosmosClientTelemetryOptions = null,
bool enableLiteClientMode = false)
{
if (serviceEndpoint == null)
{
Expand Down Expand Up @@ -947,6 +968,17 @@ internal virtual void Initialize(Uri serviceEndpoint,
this.sendingRequest,
this.receivedResponse);

if (enableLiteClientMode)
{
this.liteModeHttpClient = CosmosHttpClientCore.CreateWithConnectionPolicy(
this.ApiType,
DocumentClientEventSource.Instance,
this.ConnectionPolicy,
null,
this.sendingRequest,
this.receivedResponse);
}

// Loading VM Information (non blocking call and initialization won't fail if this call fails)
VmMetadataApiHandler.TryInitialize(this.httpClient);

Expand Down Expand Up @@ -1052,6 +1084,23 @@ private async Task<bool> GetInitializationTaskAsync(IStoreClientFactory storeCli
{
this.StoreModel = this.GatewayStoreModel;
}
// Change it to this.ConnectionPolicy.ConnectionMode == ConnectionMode.LiteClient when LiteClient is supported.
else if (this.isLiteClientEnabled)
{
ThinClientStoreModel thinClientStoreModel = new (
endpointManager: this.GlobalEndpointManager,
this.sessionContainer,
(Cosmos.ConsistencyLevel)this.accountServiceConfiguration.DefaultConsistencyLevel,
this.eventSource,
this.serializerSettings,
this.liteModeHttpClient,
new Uri(this.liteClientEndpoint),
this.accountServiceConfiguration.AccountProperties.Id);

thinClientStoreModel.SetCaches(this.partitionKeyRangeCache, this.collectionCache);

this.StoreModel = thinClientStoreModel;
}
else
{
this.InitializeDirectConnectivity(storeClientFactory);
Expand Down Expand Up @@ -6528,6 +6577,13 @@ internal IStoreModel GetStoreProxy(DocumentServiceRequest request)
return this.GatewayStoreModel;
}

if (this.isLiteClientEnabled
&& operationType == OperationType.Read
&& resourceType == ResourceType.Database)
{
return this.GatewayStoreModel;
}

if (operationType == OperationType.Create
|| operationType == OperationType.Upsert)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ private static bool IsOutOfRetries(
return !timeoutEnumerator.MoveNext(); // No more retries are configured
}

private async Task<HttpResponseMessage> ExecuteHttpHelperAsync(
public async Task<HttpResponseMessage> ExecuteHttpHelperAsync(
HttpRequestMessage requestMessage,
ResourceType resourceType,
CancellationToken cancellationToken)
Expand Down
Loading