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

Hedging: Adds support for multimaster writes #4706

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,21 @@ internal class CrossRegionHedgingAvailabilityStrategy : AvailabilityStrategyInte
/// </summary>
public TimeSpan ThresholdStep { get; private set; }

/// <summary>
/// Whether hedging for multi-master writes are enabled
/// </summary>
public bool MultiMasterWriteHedge { get; private set; }

/// <summary>
/// Constructor for hedging availability strategy
/// </summary>
/// <param name="threshold"></param>
/// <param name="thresholdStep"></param>
/// <param name="multiMasterWritesEnabled"></param>
public CrossRegionHedgingAvailabilityStrategy(
TimeSpan threshold,
TimeSpan? thresholdStep)
TimeSpan? thresholdStep,
bool multiMasterWritesEnabled = false)
{
if (threshold <= TimeSpan.Zero)
{
Expand All @@ -57,6 +64,7 @@ public CrossRegionHedgingAvailabilityStrategy(

this.Threshold = threshold;
this.ThresholdStep = thresholdStep ?? TimeSpan.FromMilliseconds(-1);
this.MultiMasterWriteHedge = multiMasterWritesEnabled;
}

/// <inheritdoc/>
Expand All @@ -70,18 +78,24 @@ internal override bool Enabled()
/// This availability strategy can only be used if the request is a read-only request on a document request.
/// </summary>
/// <param name="request"></param>
/// <param name="client"></param>
/// <returns>whether the request should be a hedging request.</returns>
internal bool ShouldHedge(RequestMessage request)
internal bool ShouldHedge(RequestMessage request, CosmosClient client)
{
//Only use availability strategy for document point operations
if (request.ResourceType != ResourceType.Document)
{
return false;
}

//check to see if it is a not a read-only request
//check to see if it is a not a read-only request/ if multimaster writes are enabled
if (!OperationTypeExtensions.IsReadOperation(request.OperationType))
{
if (this.MultiMasterWriteHedge
&& client.DocumentClient.GlobalEndpointManager.CanSupportMultipleWriteLocations(request))
{
return true;
}
return false;
}

Expand All @@ -102,7 +116,7 @@ internal override async Task<ResponseMessage> ExecuteAvailabilityStrategyAsync(
RequestMessage request,
CancellationToken cancellationToken)
{
if (!this.ShouldHedge(request)
if (!this.ShouldHedge(request, client)
|| client.DocumentClient.GlobalEndpointManager.ReadEndpoints.Count == 1)
{
return await sender(request, cancellationToken);
Expand Down
8 changes: 8 additions & 0 deletions Microsoft.Azure.Cosmos/src/Routing/GlobalEndpointManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,14 @@ public bool CanSupportMultipleWriteLocations(DocumentServiceRequest request)
&& (request.ResourceType == ResourceType.Document ||
(request.ResourceType == ResourceType.StoredProcedure && request.OperationType == OperationType.Execute));
}

public bool CanSupportMultipleWriteLocations(RequestMessage request)
{
return this.locationCache.CanUseMultipleWriteLocations()
&& this.locationCache.GetAvailableWriteLocations()?.Count > 1
&& (request.ResourceType == ResourceType.Document ||
(request.ResourceType == ResourceType.StoredProcedure && request.OperationType == OperationType.Execute));
}

#pragma warning disable VSTHRD100 // Avoid async void methods
private async void StartLocationBackgroundRefreshLoop()
Expand Down
Loading
Loading