fix(store-and-forward): re-seed queue-depth gauge from DB on sweep, clamp at 0 (review 2026-10-21 02/C3)

This commit is contained in:
Joseph Doherty
2026-10-22 08:28:40 -04:00
parent 76f7960a06
commit d3cba15699
2 changed files with 60 additions and 1 deletions
@@ -97,6 +97,37 @@ public class QueueDepthGaugeTests : IAsyncLifetime, IDisposable
return observed;
}
/// <summary>
/// Review 2026-10-21 02/C3: rows that arrive without passing through this node's counter
/// paths (LocalDb CDC on a standby) are picked up by the sweep's periodic re-seed.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Gauge_ReseedsFromDatabase_OnSweep()
{
Assert.Equal(0, ReadQueueDepthGauge());
for (var i = 0; i < 3; i++)
{
await _storage.EnqueueAsync(new StoreAndForwardMessage
{
Id = $"cdc{i}",
Category = StoreAndForwardCategory.ExternalSystem,
Target = "t",
PayloadJson = "{}",
MaxRetries = 50,
RetryIntervalMs = 3_600_000,
CreatedAt = DateTimeOffset.UtcNow,
LastAttemptAt = DateTimeOffset.UtcNow,
Status = StoreAndForwardMessageStatus.Pending,
});
}
Assert.Equal(0, ReadQueueDepthGauge()); // counter never saw them
await _service.RetryPendingMessagesAsync();
Assert.Equal(3, ReadQueueDepthGauge());
}
/// <summary>Verifies that gauge, tracks buffered depth, across enqueue drain and park.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]