From 580e00fabb55f6184a2425faee2ecd8b52feb78f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Aug 2026 08:39:36 +0000 Subject: [PATCH 1/8] Retry Cosmos database initialization Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com> --- .../Support/CosmosNoSqlTestStore.cs | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs b/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs index 767dd3b..ab70960 100644 --- a/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs +++ b/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs @@ -15,6 +15,9 @@ namespace CosmosNoSql.ConformanceTests.Support; /// The emulator does not support running multiple queries simultaneously, so we create a unique database for each test store instance. internal sealed class CosmosNoSqlTestStore(string uniqueDatabaseName) : TestStore { + private const int DatabaseCreationMaxAttempts = 30; + private static readonly TimeSpan s_databaseCreationRetryDelay = TimeSpan.FromSeconds(1); + private CosmosDbContainer? _container; private CosmosClient? _client; private Database? _database; @@ -87,7 +90,7 @@ protected override async Task StartAsync() _client = new CosmosClient(_connectionString, clientOptions); - _database = await _client.CreateDatabaseIfNotExistsAsync(uniqueDatabaseName).ConfigureAwait(false); + _database = await CreateDatabaseIfNotExistsAsync().ConfigureAwait(false); DefaultVectorStore = new CosmosNoSqlVectorStore(_database, new() { JsonSerializerOptions = SerializerOptions }); } @@ -100,6 +103,22 @@ protected override async Task StopAsync() } } + private async Task CreateDatabaseIfNotExistsAsync() + { + for (int attempt = 1; ; attempt++) + { + try + { + return await _client!.CreateDatabaseIfNotExistsAsync(uniqueDatabaseName).ConfigureAwait(false); + } + catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable && attempt < DatabaseCreationMaxAttempts) + { + TimeSpan retryDelay = ex.RetryAfter > TimeSpan.Zero ? ex.RetryAfter : s_databaseCreationRetryDelay; + await Task.Delay(retryDelay).ConfigureAwait(false); + } + } + } + private sealed class CosmosNoSqlTestJsonNamingPolicy : JsonNamingPolicy { public override string ConvertName(string name) From f0b1a7ceffd97d32f8ac1fa1934dd5f91d459333 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Aug 2026 08:40:15 +0000 Subject: [PATCH 2/8] Handle Cosmos retry-after delay Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com> --- .../Support/CosmosNoSqlTestStore.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs b/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs index ab70960..c479bd2 100644 --- a/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs +++ b/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs @@ -113,7 +113,8 @@ private async Task CreateDatabaseIfNotExistsAsync() } catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable && attempt < DatabaseCreationMaxAttempts) { - TimeSpan retryDelay = ex.RetryAfter > TimeSpan.Zero ? ex.RetryAfter : s_databaseCreationRetryDelay; + TimeSpan? retryAfter = ex.RetryAfter; + TimeSpan retryDelay = retryAfter is > TimeSpan.Zero ? retryAfter.Value : s_databaseCreationRetryDelay; await Task.Delay(retryDelay).ConfigureAwait(false); } } From 503128ee69c76a60364ff31ea07dd49a55f297aa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Aug 2026 08:40:28 +0000 Subject: [PATCH 3/8] Respect Cosmos retry-after delay Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com> --- .../Support/CosmosNoSqlTestStore.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs b/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs index c479bd2..4338dc1 100644 --- a/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs +++ b/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs @@ -114,7 +114,9 @@ private async Task CreateDatabaseIfNotExistsAsync() catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable && attempt < DatabaseCreationMaxAttempts) { TimeSpan? retryAfter = ex.RetryAfter; - TimeSpan retryDelay = retryAfter is > TimeSpan.Zero ? retryAfter.Value : s_databaseCreationRetryDelay; + TimeSpan retryDelay = retryAfter.HasValue && retryAfter.Value > TimeSpan.Zero + ? retryAfter.Value + : s_databaseCreationRetryDelay; await Task.Delay(retryDelay).ConfigureAwait(false); } } From 2df9b9773d9d99fd1d5ef59866abc9594faead4d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Aug 2026 09:02:14 +0000 Subject: [PATCH 4/8] Bound Cosmos initialization retry duration Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com> --- .../Support/CosmosNoSqlTestStore.cs | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs b/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs index 4338dc1..287da59 100644 --- a/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs +++ b/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs @@ -15,9 +15,6 @@ namespace CosmosNoSql.ConformanceTests.Support; /// The emulator does not support running multiple queries simultaneously, so we create a unique database for each test store instance. internal sealed class CosmosNoSqlTestStore(string uniqueDatabaseName) : TestStore { - private const int DatabaseCreationMaxAttempts = 30; - private static readonly TimeSpan s_databaseCreationRetryDelay = TimeSpan.FromSeconds(1); - private CosmosDbContainer? _container; private CosmosClient? _client; private Database? _database; @@ -105,18 +102,33 @@ protected override async Task StopAsync() private async Task CreateDatabaseIfNotExistsAsync() { - for (int attempt = 1; ; attempt++) + TimeSpan maximumRetryDuration = TimeSpan.FromMinutes(1); + TimeSpan fallbackRetryDelay = TimeSpan.FromSeconds(1); + System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew(); + + while (true) { try { return await _client!.CreateDatabaseIfNotExistsAsync(uniqueDatabaseName).ConfigureAwait(false); } - catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable && attempt < DatabaseCreationMaxAttempts) + catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable) { + TimeSpan remainingRetryDuration = maximumRetryDuration - stopwatch.Elapsed; + if (remainingRetryDuration <= TimeSpan.Zero) + { + throw; + } + TimeSpan? retryAfter = ex.RetryAfter; TimeSpan retryDelay = retryAfter.HasValue && retryAfter.Value > TimeSpan.Zero ? retryAfter.Value - : s_databaseCreationRetryDelay; + : fallbackRetryDelay; + if (retryDelay > remainingRetryDuration) + { + retryDelay = remainingRetryDuration; + } + await Task.Delay(retryDelay).ConfigureAwait(false); } } From becec7e90f9852f4d5e971c386eb6635a7b9d29f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Aug 2026 09:08:37 +0000 Subject: [PATCH 5/8] Simplify Cosmos initialization retry Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com> --- .../Support/CosmosNoSqlTestStore.cs | 24 ++++--------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs b/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs index 287da59..727df1e 100644 --- a/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs +++ b/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs @@ -102,11 +102,9 @@ protected override async Task StopAsync() private async Task CreateDatabaseIfNotExistsAsync() { - TimeSpan maximumRetryDuration = TimeSpan.FromMinutes(1); - TimeSpan fallbackRetryDelay = TimeSpan.FromSeconds(1); - System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew(); + DateTimeOffset deadline = DateTimeOffset.UtcNow.Add(TimeSpan.FromMinutes(1)); - while (true) + while (DateTimeOffset.UtcNow < deadline) { try { @@ -114,24 +112,12 @@ private async Task CreateDatabaseIfNotExistsAsync() } catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable) { - TimeSpan remainingRetryDuration = maximumRetryDuration - stopwatch.Elapsed; - if (remainingRetryDuration <= TimeSpan.Zero) - { - throw; - } - - TimeSpan? retryAfter = ex.RetryAfter; - TimeSpan retryDelay = retryAfter.HasValue && retryAfter.Value > TimeSpan.Zero - ? retryAfter.Value - : fallbackRetryDelay; - if (retryDelay > remainingRetryDuration) - { - retryDelay = remainingRetryDuration; - } - + TimeSpan retryDelay = ex.RetryAfter.HasValue ? ex.RetryAfter.Value : TimeSpan.FromMilliseconds(200); await Task.Delay(retryDelay).ConfigureAwait(false); } } + + throw new TimeoutException("Cosmos DB did not become available within one minute."); } private sealed class CosmosNoSqlTestJsonNamingPolicy : JsonNamingPolicy From a245783f49064abbf6826e2f691f429b54ab3b3f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Aug 2026 09:09:25 +0000 Subject: [PATCH 6/8] Bound Cosmos retry delay by deadline Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com> --- .../Support/CosmosNoSqlTestStore.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs b/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs index 727df1e..6ebaa77 100644 --- a/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs +++ b/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs @@ -113,7 +113,13 @@ private async Task CreateDatabaseIfNotExistsAsync() catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable) { TimeSpan retryDelay = ex.RetryAfter.HasValue ? ex.RetryAfter.Value : TimeSpan.FromMilliseconds(200); - await Task.Delay(retryDelay).ConfigureAwait(false); + TimeSpan remainingTime = deadline - DateTimeOffset.UtcNow; + if (remainingTime <= TimeSpan.Zero) + { + break; + } + + await Task.Delay(retryDelay < remainingTime ? retryDelay : remainingTime).ConfigureAwait(false); } } From 1e8ef74152e8aee38b74f99468e4280fb00bb4ae Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Aug 2026 09:10:03 +0000 Subject: [PATCH 7/8] Avoid zero Cosmos retry delays Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com> --- .../Support/CosmosNoSqlTestStore.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs b/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs index 6ebaa77..f3b47f3 100644 --- a/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs +++ b/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs @@ -112,7 +112,9 @@ private async Task CreateDatabaseIfNotExistsAsync() } catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable) { - TimeSpan retryDelay = ex.RetryAfter.HasValue ? ex.RetryAfter.Value : TimeSpan.FromMilliseconds(200); + TimeSpan retryDelay = ex.RetryAfter.HasValue && ex.RetryAfter.Value > TimeSpan.Zero + ? ex.RetryAfter.Value + : TimeSpan.FromMilliseconds(200); TimeSpan remainingTime = deadline - DateTimeOffset.UtcNow; if (remainingTime <= TimeSpan.Zero) { From fc67a15d1ca3a859c6b2074eb0feb0da42cf6ee2 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Wed, 19 Aug 2026 11:34:35 +0200 Subject: [PATCH 8/8] Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Adam Sitnik --- .../Support/CosmosNoSqlTestStore.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs b/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs index f3b47f3..0998d11 100644 --- a/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs +++ b/MEVD/test/CosmosNoSql.ConformanceTests/Support/CosmosNoSqlTestStore.cs @@ -87,7 +87,7 @@ protected override async Task StartAsync() _client = new CosmosClient(_connectionString, clientOptions); - _database = await CreateDatabaseIfNotExistsAsync().ConfigureAwait(false); + _database = await CreateDatabaseWithRetryAsync().ConfigureAwait(false); DefaultVectorStore = new CosmosNoSqlVectorStore(_database, new() { JsonSerializerOptions = SerializerOptions }); } @@ -100,7 +100,7 @@ protected override async Task StopAsync() } } - private async Task CreateDatabaseIfNotExistsAsync() + private async Task CreateDatabaseWithRetryAsync() { DateTimeOffset deadline = DateTimeOffset.UtcNow.Add(TimeSpan.FromMinutes(1));