Keep notification acknowledgements responsive under snapshot contention #439

Closed
opened 2026-08-10 01:08:31 +00:00 by timmy · 0 comments
Owner

Problem

After Gitea confirms a notification acknowledgement, the async API request synchronously opens an immediate SQLite transaction to update the shared live snapshot. Lock contention can therefore stall the event loop for about the configured one-second busy timeout, delaying unrelated live polling, health checks, searches, and authored actions. Bulk acknowledgement repeats that transaction once per successful notification.

Product slice

Make post-acknowledgement snapshot maintenance non-blocking and batch-atomic:

  • remove all successfully acknowledged notification IDs in one shared-snapshot transaction;
  • run shared SQLite maintenance off the async event loop;
  • preserve immediate process-local removal and stale-refresh suppression;
  • treat shared snapshot contention as cache degradation after Gitea has confirmed the mutation, not as a false mutation failure.

Acceptance tests

  1. A held shared-snapshot write lock does not block an async event-loop heartbeat while a confirmed acknowledgement performs cache maintenance.
  2. A bulk acknowledgement removes all successful IDs with one store operation and one notification revision advance.
  3. Partial batches remove only successful IDs; failed IDs remain visible and are reported as failed.
  4. A stale concurrent refresh cannot resurrect acknowledged IDs.
  5. Single acknowledgement and the full suite remain green.

Evidence and non-duplication

Current origin/main calls synchronous LiveSnapshotStore.remove_notification() from async single and bulk routes; the store uses BEGIN IMMEDIATE and a one-second SQLite busy timeout. Historical issue/PR titles and recent commits cover bounded upstream fan-out (#145), idempotency/session database isolation (#248/#275/#311), and cross-worker refresh coalescing (#433), but not non-blocking batch acknowledgement snapshot maintenance.

## Problem After Gitea confirms a notification acknowledgement, the async API request synchronously opens an immediate SQLite transaction to update the shared live snapshot. Lock contention can therefore stall the event loop for about the configured one-second busy timeout, delaying unrelated live polling, health checks, searches, and authored actions. Bulk acknowledgement repeats that transaction once per successful notification. ## Product slice Make post-acknowledgement snapshot maintenance non-blocking and batch-atomic: - remove all successfully acknowledged notification IDs in one shared-snapshot transaction; - run shared SQLite maintenance off the async event loop; - preserve immediate process-local removal and stale-refresh suppression; - treat shared snapshot contention as cache degradation after Gitea has confirmed the mutation, not as a false mutation failure. ## Acceptance tests 1. A held shared-snapshot write lock does not block an async event-loop heartbeat while a confirmed acknowledgement performs cache maintenance. 2. A bulk acknowledgement removes all successful IDs with one store operation and one notification revision advance. 3. Partial batches remove only successful IDs; failed IDs remain visible and are reported as failed. 4. A stale concurrent refresh cannot resurrect acknowledged IDs. 5. Single acknowledgement and the full suite remain green. ## Evidence and non-duplication Current `origin/main` calls synchronous `LiveSnapshotStore.remove_notification()` from async single and bulk routes; the store uses `BEGIN IMMEDIATE` and a one-second SQLite busy timeout. Historical issue/PR titles and recent commits cover bounded upstream fan-out (#145), idempotency/session database isolation (#248/#275/#311), and cross-worker refresh coalescing (#433), but not non-blocking batch acknowledgement snapshot maintenance.
timmy self-assigned this 2026-08-10 01:08:31 +00:00
timmy closed this issue 2026-08-10 01:16:03 +00:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: stackchain/stackchain-dashboard#439
No description provided.