fix(site-call-audit): reconciliation pull serves only un-acked tracking rows (node-local ack ledger), batched page upsert, prune removed sites' cursors (review 2026-10-21 06/PERF-2 + lane H follow-up)
This commit is contained in:
+48
@@ -416,6 +416,54 @@ public class SiteAuditTelemetryActorTests : TestKit
|
||||
Assert.Equal(expectedIds, emittedEventIds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that the tracking-row versions central ACCEPTED are recorded as central acks
|
||||
/// in the tracking store — and only those — so the SiteCalls reconciliation pull stops
|
||||
/// re-serving them (review 2026-10-21 06/PERF-2).
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task CachedDrain_AcceptedPackets_AreRecordedAsCentralAcks()
|
||||
{
|
||||
var acceptedRow = NewCachedEvent(AuditKind.CachedSubmit);
|
||||
var refusedRow = NewCachedEvent(AuditKind.CachedSubmit);
|
||||
_queue.ReadPendingAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<IReadOnlyList<AuditEvent>>(Array.Empty<AuditEvent>()));
|
||||
_queue.ReadPendingCachedTelemetryAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||
.Returns(
|
||||
Task.FromResult<IReadOnlyList<AuditEvent>>(new[] { acceptedRow, refusedRow }),
|
||||
Task.FromResult<IReadOnlyList<AuditEvent>>(Array.Empty<AuditEvent>()));
|
||||
|
||||
var acceptedTid = new TrackedOperationId(acceptedRow.CorrelationId!.Value);
|
||||
var refusedTid = new TrackedOperationId(refusedRow.CorrelationId!.Value);
|
||||
var acceptedSnapshot = NewSnapshot(acceptedTid) with
|
||||
{
|
||||
UpdatedAtUtc = new DateTime(2026, 5, 20, 10, 0, 7, DateTimeKind.Utc),
|
||||
};
|
||||
_trackingStore.GetStatusAsync(acceptedTid, Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<TrackingStatusSnapshot?>(acceptedSnapshot));
|
||||
_trackingStore.GetStatusAsync(refusedTid, Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<TrackingStatusSnapshot?>(NewSnapshot(refusedTid)));
|
||||
|
||||
_client.IngestCachedTelemetryAsync(Arg.Any<CachedTelemetryBatch>(), Arg.Any<CancellationToken>())
|
||||
.Returns(_ =>
|
||||
{
|
||||
var ack = new IngestAck();
|
||||
ack.AcceptedEventIds.Add(acceptedRow.EventId.ToString());
|
||||
return Task.FromResult(ack);
|
||||
});
|
||||
|
||||
CreateActorWithCachedDrain();
|
||||
|
||||
await AwaitAssertAsync(async () =>
|
||||
{
|
||||
await _trackingStore.Received(1).RecordCentralAcksAsync(
|
||||
Arg.Is<IReadOnlyDictionary<TrackedOperationId, DateTime>>(d =>
|
||||
d.Count == 1 && d[acceptedTid] == acceptedSnapshot.UpdatedAtUtc),
|
||||
Arg.Any<CancellationToken>());
|
||||
}, TimeSpan.FromSeconds(5));
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a cached row with no tracking snapshot past the grace period is abandoned while a valid row still flows.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user