fix(auditlog): reconciliation pull serves only unacked rows (PushAbandoned/Rejected push-exit states), central pages within a tick with set-based inserts; refused push rows leave the queue after N attempts (review 2026-10-21 06/PERF-1, 06/COR-3, 06/IMPL-1)

This commit is contained in:
Joseph Doherty
2026-10-22 06:38:02 -04:00
parent 1da5d0bac4
commit 9e7e19c3c1
13 changed files with 873 additions and 116 deletions
@@ -3,8 +3,9 @@ namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
/// <summary>
/// Tuning knobs for the central <see cref="SiteAuditReconciliationActor"/> singleton.
/// Defaults: pull every 5 minutes per site, 256 rows per
/// batch, declare a site "stalled" after two consecutive pull cycles return non-empty
/// AND <c>MoreAvailable=true</c> (the backlog is not draining).
/// page and up to 50 pages per site per tick, declare a site "stalled" after two
/// consecutive cycles still end non-empty AND <c>MoreAvailable=true</c> after the page cap
/// (the backlog is not draining).
/// </summary>
/// <remarks>
/// <para>
@@ -77,6 +78,15 @@ public sealed class SiteAuditReconciliationOptions
/// </summary>
public int BatchSize { get; set; } = 256;
/// <summary>
/// Maximum <c>PullAuditEvents</c> pages issued against one site in one tick while the
/// site keeps reporting <c>MoreAvailable</c> (review 2026-10-21 06/PERF-1, mirroring
/// <c>SiteCallAuditActor</c>'s 50-page bound). Bounds a misbehaving site's per-tick cost
/// while letting a busy-but-healthy site drain inside one tick, so the stalled signal
/// only fires on a genuine non-drain.
/// </summary>
public int MaxPagesPerTick { get; set; } = 50;
/// <summary>
/// Number of consecutive non-draining cycles (events returned AND
/// <c>MoreAvailable=true</c>) that must accumulate for a site before the actor