Skip to content

announcements: a dropped aired-confirmation re-arms the row and airs it twice — make delivery at-least-once #773

Description

@genwave-radio

From the 2026-09-10 repository review (R04), re-verified on v5.8.2. Ruling 2026-09-15: at-least-once delivery; a lost confirmation may re-air an announcement once, never silently drop it.

Problem.

  • AnnouncementAiredEventSink.cs:38 — TryWrite on the bounded channel; queue-full drops the engine-confirmed TrackAired signal.
  • AnnouncementAiredDrainService.cs:12 — a failed MarkAiredAsync write is logged and dropped, "never retried here".
  • AnnouncementLifecycleGuardianService.cs — the row stays claimed; after the grace period the guardian re-arms it to pending, and the announcement airs again.
  • A restart between air and persist loses the in-memory queue.

Scope (at-least-once).

  • Bounded retry with backoff in the drain service; idempotent MarkAiredAsync (a second confirmation is a no-op, not a second lifecycle transition or booth-log line).
  • Queue-full: retry the enqueue briefly rather than drop; log at Warning with the announcement id if it still cannot land.
  • Booth-log append failure after a successful lifecycle write is handled separately from the lifecycle write failure.
  • Operator wording: lifecycle states say "confirmed" only when the write landed.

Acceptance.

  • Test: claim → genuine aired event → store fails once → store recovers → row ends aired, guardian never re-arms it.
  • Test: duplicate confirmation for one id causes one transition and one booth-log line.
  • Test: restart between air and persist → announcement airs again at most once (documented, not silent).
  • No synchronous DB work on the audio callback.

Out of scope: MediaRotationDrainService (rotation ledger drops are approximate accounting and acceptable); a durable local journal (rejected 2026-09-15 as more machinery than a small community needs).

Preserve gh-#612's engine-confirmed-airing behaviour.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium prioritybugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions