Files
ScadaBridge/src/ZB.MOM.WW.ScadaBridge.SiteCallAudit/SiteCallReconciliationPinnedChanged.cs
T
Joseph Doherty 20098c6108 fix(site-call-audit): composite keyset cursor eliminates the single-timestamp reconciliation pin; pinned state now a published event
Reconciliation cursor becomes composite (UpdatedAtUtc, TrackedOperationId);
IPullSiteCallsClient/GrpcPullSiteCallsClient forward the Task-15 after_id keyset
(additive param, null preserves the legacy inclusive >= contract). A burst
sharing one exact UpdatedAtUtc now drains via the id tiebreak instead of pinning
forever. A legacy site that ignores after_id is latched + published as
SiteCallReconciliationPinnedChanged on the EventStream (transition-only),
replacing the prior silent log line.
2026-07-09 08:44:07 -04:00

20 lines
1.2 KiB
C#

namespace ZB.MOM.WW.ScadaBridge.SiteCallAudit;
/// <summary>
/// Published on the actor system EventStream when a site's Site Call Audit
/// reconciliation puller transitions into or out of the "pinned" state — the
/// composite <c>(UpdatedAtUtc, TrackedOperationId)</c> keyset cursor could not
/// advance yet the site still reports <c>MoreAvailable=true</c>, so the backlog
/// tail cannot be drained. In practice this only happens against a legacy site
/// that ignores the <c>after_id</c> keyset field (a modern site drains a
/// single-timestamp burst via the id tiebreak). Mirrors
/// <c>SiteAuditTelemetryStalledChanged</c>: only transitions are published
/// (<c>Pinned=true</c> on latch, <c>Pinned=false</c> when progress resumes), so
/// a downstream health subscriber never sees a flood of redundant notifications.
/// The dead-end that the previous implementation only logged is now a
/// health-observable condition.
/// </summary>
/// <param name="SiteId">The site whose reconciliation cursor pinned (or unpinned).</param>
/// <param name="Pinned">True on entering the pinned state; false when the cursor makes progress again.</param>
public sealed record SiteCallReconciliationPinnedChanged(string SiteId, bool Pinned);