Repository navigation
Compactions keep running while a commit waits to plan - #40
Conversation
…it's marked compacting; the sweep re-queues lost ones on the same rule
…: claims refresh as merges start and pieces finish
…he sweep re-queues a session's compactions only once none of its claims has moved
… and 96 per account, not 32 and 64
|
Two commits on top, from the Crossref trial: 1. A smaller version of the same race, in 2. The 15-minute sweep in a backed-up queue. A claim is refreshed only when its merge starts and as pieces finish. On the full dump, thousands of pieces sit in the bulk queue at a time, so plenty of claims go quiet for 15 minutes just waiting their turn. Re-queueing those adds duplicate pieces to the same backlog, which delays everything further. Changes:
3. Concurrency.
Server tests 251/251, typecheck, oxlint and oxfmt clean. |
Fixes a race in #39 that stalled a large commit on staging (session
568fc1c9, 2026-10-15), and shortens how long a lost compaction waits.What happened. A commit request moves the session to
committingstraight away, but the phase that says it is compacting (commitPhase: 'compacting') is set later, by thepush.commitjob. Compaction jobs only treated a committing session as active once that phase was set. So a compaction that ran in the gap, which was every compaction queued just before the request, decided the session no longer wanted it and returned. Its runs stayed claimed.The stalled-compaction sweep was the only way back, and it re-queued a claim only once it was 30 minutes old. On staging, 176 of 190 runs were claimed by compactions that had quit; the queue was empty and every job had acknowledged its message. The loader's log showed it exactly:
compacting 190 runs (176 being merged)for 30 minutes, then 175, 115 and 85 runs in the three minutes after the sweep re-queued them.The fix. A compaction keeps running while its session is open, or committing and not yet planned (
commitPlanis null). Once the commit has planned, it reads the run list it planned from, so a compaction finishing after that changes nothing. A compaction that finishes while a serial commit reads the runs is harmless: that commit read the run list once, and every input stays in storage. The sweep's re-queue of lost compactions uses the same rule.Faster recovery. A compaction claim is refreshed when its merge starts and after each piece, and a piece takes minutes. So the sweep now re-queues a claim after 15 quiet minutes (
recoverConfig.compactionStaleMs), not the 30 used for commit stalls. The sweep runs every 10 minutes, so a lost compaction comes back within 15 to 25 minutes instead of 30 to 40. The cost: a compaction that waits more than 15 minutes in a backed-up queue before it starts may run twice. That's safe, because each piece is skipped if it's already written.Tests.
recover.test.tsadds three:The first two fail without the fix. Server tests 250/250, typecheck and oxlint clean.
Not merged or deployed: a commit is in flight on staging and recovers on its own through the sweep.