perf(comms+audit): close phase-2 residuals — direct ingest path, monotonic timeouts, synthetic probe, not-reporting set, cursor-exact audit pull

This commit is contained in:
Joseph Doherty
2026-08-14 21:38:23 -04:00
parent 4cd1441984
commit a5882753dd
38 changed files with 1254 additions and 443 deletions
+22 -14
View File
@@ -343,21 +343,29 @@ mapping/unexpected fault collapses to empty without a second dial (the other
node would hit the same fault). The same resolution + failover applies to Site
Call Audit's `PullSiteCalls`.
**Cursor keyset.** The site side of the composite `(OccurredAtUtc, EventId)`
keyset now exists (WP2.3): `PullAuditEventsRequest.after_id` (additive field 3)
mirrors `PullSiteCallsRequest.after_id`, and `ISiteAuditQueue.ReadPendingSinceAsync`
switches from the inclusive `OccurredAtUtc >= since` to a strict composite
comparison when it is set, so a burst sharing one instant drains via the id
tiebreak instead of pinning the cursor.
**Cursor keyset.** The composite `(OccurredAtUtc, EventId)` keyset is wired end to
end. `PullAuditEventsRequest.after_id` (additive field 3) mirrors
`PullSiteCallsRequest.after_id`; `ISiteAuditQueue.ReadPendingSinceAsync` switches
from the inclusive `OccurredAtUtc >= since` to a strict composite comparison when it
is set, so a burst sharing one instant drains via the id tiebreak instead of pinning
the cursor; and `IPullAuditEventsClient` /`GrpcPullAuditEventsClient` /
`SiteAuditReconciliationActor` populate it — the actor's per-site watermark is the
`(timestamp, id)` pair of the highest row ingested, threaded back into the next pull,
mirroring `SiteCallAuditActor`'s `PullSiteCalls` cursor exactly.
> **Central still sends a bare timestamp (tracked follow-up).**
> `IPullAuditEventsClient`/`SiteAuditReconciliationActor` do not yet populate
> `after_id`, so today's cursor remains a single `sinceUtc` under the legacy
> inclusive read. Two consequences, both benign: a window whose rows all share one
> instant re-serves rather than advancing (idempotent on `EventId`, as before), and
> the rows **at** the cursor instant cannot be proven received, so they stay
> servable until a newer row moves the cursor. Wiring `after_id` at central makes
> the retirement exact; the site accepts it already.
That makes retirement **exact**: `MarkReconciledUpToAsync` is handed the id half, so
the rows **at** the cursor instant are proven received and retired, where a bare
timestamp could only prove receipt of rows strictly older than itself and left the
boundary rows servable until a newer row moved the cursor. `after_id` is null only on
the first pull for a site (and against a site that predates the field), which keeps
the legacy inclusive `>=` read as the compatible fallback. The cursor stays in-memory
and resets on singleton restart; idempotent `InsertIfNotExistsAsync` still absorbs any
re-pulled duplicates, so exactness is an optimization, not a correctness dependency.
Unlike Site Call Audit, this actor issues ONE pull per tick rather than paging within
it — a lagging drain is meant to surface as the stalled signal. The id tiebreak is
what makes that safe against a same-instant burst larger than one batch: the cursor
advances on every tick even when the timestamp cannot.
### Central direct-write (central-originated events)