fix(historian): preserve stable alarm delivery identities
v2-ci / build (pull_request) Successful in 5m52s
v2-ci / unit-tests (pull_request) Failing after 1h23m55s

This commit is contained in:
Joseph Doherty
2026-10-13 07:10:58 -04:00
parent 0ccfbbee5c
commit 109163621c
13 changed files with 341 additions and 27 deletions
+13
View File
@@ -153,6 +153,19 @@ Ordering follows from that: the drain reads in `enqueued_at_utc` order (with `id
as a tiebreak so the ordering is total), because a hashed key carries no
insertion sequence.
Gateway delivery carries a separate nonzero `DeliveryId` GUID. Direct event instances
create it once; retries and record copies preserve it. It is excluded from queue JSON
and business equality, so the existing payload fingerprint and pair deduplication stay
unchanged. The drain derives its delivery GUID solely from the persisted row `id`,
including migrated legacy rows. It never hashes a reconstructed payload or mints an ID
per send. The versioned encoding in `AlarmDeliveryIds` therefore survives retry,
restart, payload edits and replicated failover without a schema migration.
Different business payloads at the same timestamp remain distinct; completely identical
payloads deliberately converge. An explicitly empty direct delivery ID is rejected.
The Gateway mapper sends this GUID as the wire event ID; the live alarm readback test
requires that exact ID. SQL Server and QuestDB retain their existing event-ID schemes.
`EnqueueAsync` does a single `INSERT … ON CONFLICT DO NOTHING` on the hot path.
To avoid a `SELECT COUNT(*)` on every enqueue, the sink keeps an in-memory
non-dead-lettered row counter (seeded at startup, kept current by every mutation,