diff --git a/Microsoft.Azure.Cosmos/src/Routing/AvailabilityStrategy/CrossRegionHedgingAvailabilityStrategy.cs b/Microsoft.Azure.Cosmos/src/Routing/AvailabilityStrategy/CrossRegionHedgingAvailabilityStrategy.cs index a6ed3bfea7..1fd060b906 100644 --- a/Microsoft.Azure.Cosmos/src/Routing/AvailabilityStrategy/CrossRegionHedgingAvailabilityStrategy.cs +++ b/Microsoft.Azure.Cosmos/src/Routing/AvailabilityStrategy/CrossRegionHedgingAvailabilityStrategy.cs @@ -143,7 +143,7 @@ internal override async Task ExecuteAvailabilityStrategyAsync( request, hedgeRegions.ElementAt(requestNumber), cancellationToken, - cancellationTokenSource); + cancellationTokenSource, trace); requestTasks.Add(primaryRequest); } @@ -262,7 +262,7 @@ private async Task CloneAndSendAsync( clonedRequest, region, cancellationToken, - cancellationTokenSource); + cancellationTokenSource, trace); } } @@ -271,7 +271,7 @@ private async Task RequestSenderAndResultCheckAsync( RequestMessage request, string hedgedRegion, CancellationToken cancellationToken, - CancellationTokenSource cancellationTokenSource) + CancellationTokenSource cancellationTokenSource, ITrace trace) { try { @@ -288,9 +288,9 @@ private async Task RequestSenderAndResultCheckAsync( return new HedgingResponse(false, response, hedgedRegion); } - catch (OperationCanceledException) when (cancellationTokenSource.IsCancellationRequested) + catch (OperationCanceledException oce ) when (cancellationTokenSource.IsCancellationRequested) { - return new HedgingResponse(false, null, hedgedRegion); + throw new CosmosOperationCanceledException(oce, trace); } catch (Exception ex) { diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosAvailabilityStrategyTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosAvailabilityStrategyTests.cs index 32173e79bd..56966373d6 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosAvailabilityStrategyTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosAvailabilityStrategyTests.cs @@ -840,6 +840,60 @@ public async Task AvailabilityStrategyStepTests(string operation, string condito } } + [TestMethod] + [TestCategory("MultiRegion")] + [ExpectedException(typeof(CosmosOperationCanceledException))] + public async Task AvailabilityStrategyWithCancellationTokenThrowsExceptionTest() + { + FaultInjectionRule responseDelay = new FaultInjectionRuleBuilder( + id: "responseDely", + condition: + new FaultInjectionConditionBuilder() + .WithRegion("Central US") + .WithOperationType(FaultInjectionOperationType.ReadItem) + .Build(), + result: + FaultInjectionResultBuilder.GetResultBuilder(FaultInjectionServerErrorType.ResponseDelay) + .WithDelay(TimeSpan.FromMilliseconds(6000)) + .Build()) + .WithDuration(TimeSpan.FromMinutes(90)) + .WithHitLimit(2) + .Build(); + + List rules = new List() { responseDelay }; + FaultInjector faultInjector = new FaultInjector(rules); + + responseDelay.Disable(); + + CosmosClientOptions clientOptions = new CosmosClientOptions() + { + ConnectionMode = ConnectionMode.Direct, + ApplicationPreferredRegions = new List() { "Central US", "North Central US" }, + AvailabilityStrategy = AvailabilityStrategy.CrossRegionHedgingStrategy( + threshold: TimeSpan.FromMilliseconds(300), + thresholdStep: null), + Serializer = this.cosmosSystemTextJsonSerializer + }; + + using (CosmosClient faultInjectionClient = new CosmosClient( + connectionString: this.connectionString, + clientOptions: faultInjector.GetFaultInjectionClientOptions(clientOptions))) + { + CancellationTokenSource cts = new CancellationTokenSource(); + cts.Cancel(); + + Database database = faultInjectionClient.GetDatabase(CosmosAvailabilityStrategyTests.dbName); + Container container = database.GetContainer(CosmosAvailabilityStrategyTests.containerName); + + ItemResponse ir = await container.ReadItemAsync( + "testId", + new PartitionKey("pk"), cancellationToken: cts.Token + ); + + } + + } + private static async Task HandleChangesAsync( ChangeFeedProcessorContext context, IReadOnlyCollection changes,