Skip to content
Open
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
57 changes: 43 additions & 14 deletions Microsoft.Azure.Cosmos/src/Routing/LocationCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -947,23 +947,52 @@ internal bool CanUseMultipleWriteLocations()
return this.useMultipleWriteLocations && this.enableMultipleWriteLocations;
}

internal Uri ResolveThinClientEndpoint(DocumentServiceRequest request, bool isReadRequest)
{
internal Uri ResolveThinClientEndpoint(DocumentServiceRequest request, bool isReadRequest)
{
if (request.RequestContext != null && request.RequestContext.LocationEndpointToRoute != null)
{
return request.RequestContext.LocationEndpointToRoute;
}

DatabaseAccountLocationsInfo snapshot = this.locationInfo;
ReadOnlyCollection<Uri> endpoints = isReadRequest
? snapshot.ThinClientReadEndpoints
: snapshot.ThinClientWriteEndpoints;

int locationIndex = request.RequestContext.LocationIndexToRoute.GetValueOrDefault(0);
Uri chosenEndpoint = endpoints[locationIndex % endpoints.Count];

request.RequestContext.RouteToLocation(chosenEndpoint);
return chosenEndpoint;
}

DatabaseAccountLocationsInfo snapshot = this.locationInfo;
ReadOnlyCollection<Uri> endpoints = this.GetApplicableThinClientEndpoints(request, isReadRequest, snapshot);

int locationIndex = request.RequestContext.LocationIndexToRoute.GetValueOrDefault(0);
Uri chosenEndpoint = endpoints[locationIndex % endpoints.Count];

request.RequestContext.RouteToLocation(chosenEndpoint);
return chosenEndpoint;
}

/// <summary>
/// Resolves the applicable thin client endpoints for a request, honoring per-request
/// <see cref="DocumentServiceRequestContext.ExcludeRegions"/>. Mirrors the gateway
/// path in <see cref="GetApplicableEndpoints(DocumentServiceRequest, bool)"/>.
/// </summary>
/// <remarks>
/// When all preferred regions are excluded, falls back to the first thin client write
/// endpoint (which itself falls back to <see cref="defaultEndpoint"/> at initialization
/// time). This keeps requests on the thin client routing path rather than dropping back
/// to the gateway endpoint and breaking thin client port semantics.
/// </remarks>
private ReadOnlyCollection<Uri> GetApplicableThinClientEndpoints(
DocumentServiceRequest request,
bool isReadRequest,
DatabaseAccountLocationsInfo snapshot)
{
IReadOnlyList<string> excludeRegions = request.RequestContext?.ExcludeRegions;
if (excludeRegions == null || excludeRegions.Count == 0)
{
return isReadRequest ? snapshot.ThinClientReadEndpoints : snapshot.ThinClientWriteEndpoints;
}

Uri fallbackEndpoint = snapshot.ThinClientWriteEndpoints[0];

return GetApplicableEndpoints(
isReadRequest ? snapshot.ThinClientReadEndpointByLocation : snapshot.ThinClientWriteEndpointByLocation,
snapshot.EffectivePreferredLocations,
fallbackEndpoint,
excludeRegions);
}

private void SetServicePointConnectionLimit(Uri endpoint)
Expand Down
Loading
Loading