diff --git a/Microsoft.Azure.Cosmos/src/DocumentClient.cs b/Microsoft.Azure.Cosmos/src/DocumentClient.cs index 8176b020b9..b8046e938a 100644 --- a/Microsoft.Azure.Cosmos/src/DocumentClient.cs +++ b/Microsoft.Azure.Cosmos/src/DocumentClient.cs @@ -6866,9 +6866,20 @@ internal void InitializePartitionLevelFailoverWithDefaultHedging() { // The default threshold is the minimum value of 1 second and a fraction (currently it's half) of // the request timeout value provided by the end customer. - double defaultThresholdInMillis = Math.Min( - DocumentClient.DefaultHedgingThresholdInMilliseconds, - this.ConnectionPolicy.RequestTimeout.TotalMilliseconds / 2); + double defaultThresholdInMillis; + + if (this.ConnectionPolicy.RequestTimeout.TotalMilliseconds == 0) + { + // If the request timeout is 0, we will use the default hedging theshold value + defaultThresholdInMillis = DocumentClient.DefaultHedgingThresholdInMilliseconds; + DefaultTrace.TraceWarning("DocumentClient: Request timeout is set to 0, which is not a valid value. Falling back to default hedging threshold of {0} ms", defaultThresholdInMillis); + } + else + { + defaultThresholdInMillis = Math.Min( + DocumentClient.DefaultHedgingThresholdInMilliseconds, + this.ConnectionPolicy.RequestTimeout.TotalMilliseconds / 2); + } this.ConnectionPolicy.AvailabilityStrategy = AvailabilityStrategy.SDKDefaultCrossRegionHedgingStrategyForPPAF( threshold: TimeSpan.FromMilliseconds(defaultThresholdInMillis), diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemIntegrationTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemIntegrationTests.cs index 27a1d98338..646cc28f8d 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemIntegrationTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemIntegrationTests.cs @@ -2195,6 +2195,70 @@ public async Task CreateItemAsync_WithThinClientEnabledAndCircuitBreakerEnabledA await this.TryDeleteItems(itemsList); } } + + [TestMethod] + [Owner("ntripician")] + [TestCategory("MultiRegion")] + [Timeout(70000)] + public async Task ClinetOverrides0msRequestTimeoutValueForPPAF() + { + // Arrange. + + // Now that the ppaf enablement flag is returned from gateway, we need to intercept the response and remove the flag from the response, so that + // the environment variable set above is honored. + HttpClientHandlerHelper httpClientHandlerHelper = new HttpClientHandlerHelper() + { + ResponseIntercepter = async (response, request) => + { + string json = await response?.Content?.ReadAsStringAsync(); + if (json.Length > 0 && json.Contains("enablePerPartitionFailoverBehavior")) + { + JObject parsedDatabaseAccountResponse = JObject.Parse(json); + parsedDatabaseAccountResponse.Property("enablePerPartitionFailoverBehavior").Value = "true"; + + HttpResponseMessage interceptedResponse = new() + { + StatusCode = response.StatusCode, + Content = new StringContent(parsedDatabaseAccountResponse.ToString()), + Version = response.Version, + ReasonPhrase = response.ReasonPhrase, + RequestMessage = response.RequestMessage, + }; + + return interceptedResponse; + } + + return response; + }, + }; + + List preferredRegions = new List { region1, region2, region3 }; + CosmosClientOptions cosmosClientOptions = new CosmosClientOptions() + { + ConsistencyLevel = ConsistencyLevel.Session, + RequestTimeout = TimeSpan.FromSeconds(0), + ApplicationPreferredRegions = preferredRegions, + HttpClientFactory = () => new HttpClient(httpClientHandlerHelper), + }; + + + using CosmosClient cosmosClient = new(connectionString: this.connectionString, clientOptions: cosmosClientOptions); + Database database = cosmosClient.GetDatabase(MultiRegionSetupHelpers.dbName); + Container container = database.GetContainer(MultiRegionSetupHelpers.containerName); + + try + { + //request to start document client initiation + _ = await container.ReadItemAsync("id", new PartitionKey("pk1")); + } + catch { } + + // Act and Assert. + + CrossRegionHedgingAvailabilityStrategy strat = cosmosClient.DocumentClient.ConnectionPolicy.AvailabilityStrategy as CrossRegionHedgingAvailabilityStrategy; + Assert.IsNotNull(strat); + Assert.AreNotEqual(0, strat.Threshold); + } private async Task TryCreateItems(List testItems) {