Archive writers are never closed at shutdown, so their -wal survives a clean stop #280

Open
opened 2026-08-24 03:05:51 +02:00 by clawbot · 0 comments
Collaborator

Found and measured during the rework of #256, and deliberately left out of that PR because closing archive writers is a change to the archive lifecycle rather than part of the durability fix.

The delivery engine caches archive writers and never closes them on shutdown. After a clean stop, the archive database's -wal sidecar still holds the data: measured with archive-*.db carrying no schema at all and the -wal holding all 8 rows.

Not a correctness hole today. cp -a of the whole DATA_DIR — which is what the documented backup procedure does — carries the sidecars, so nothing is lost by following the docs. #263 documents the behaviour rather than leaving it silent.

But it makes the archive a three-file artifact where an operator reasonably expects one. Anyone who moves or copies archive-<id>.db on its own — the obvious thing to do with a file named that — gets an empty database and no warning. That is the shape of a foot-gun rather than a bug.

Definition of done

  • Archive writers are closed in the delivery engine's OnStop hook, so a clean shutdown checkpoints and removes the -wal.
  • A test asserting no archive-*.db-wal survives a clean shutdown.
  • The README caveat added by #263 documenting this gap is reverted, since it will no longer be true.
  • Confirm the close path cannot block or panic if a writer is mid-write when the stop hook fires, and that it respects the existing stop-context budget rather than extending shutdown past it — #134 and #102 set that budget and must not regress.
  • Confirm a kill -9 still leaves recoverable state — this makes the CLEAN path single-file, it must not make the unclean path worse.

Not milestoned: no data is lost under the documented procedure, and the fix touches shutdown ordering, which is worth doing carefully rather than quickly.

Found and measured during the rework of https://git.eeqj.de/sneak/webhooker/issues/256, and deliberately left out of that PR because closing archive writers is a change to the archive lifecycle rather than part of the durability fix. The delivery engine caches archive writers and never closes them on shutdown. After a clean stop, the archive database's `-wal` sidecar still holds the data: measured with `archive-*.db` carrying no schema at all and the `-wal` holding all 8 rows. Not a correctness hole today. `cp -a` of the whole `DATA_DIR` — which is what the documented backup procedure does — carries the sidecars, so nothing is lost by following the docs. https://git.eeqj.de/sneak/webhooker/pulls/263 documents the behaviour rather than leaving it silent. But it makes the archive a three-file artifact where an operator reasonably expects one. Anyone who moves or copies `archive-<id>.db` on its own — the obvious thing to do with a file named that — gets an empty database and no warning. That is the shape of a foot-gun rather than a bug. ## Definition of done - Archive writers are closed in the delivery engine's `OnStop` hook, so a clean shutdown checkpoints and removes the `-wal`. - A test asserting no `archive-*.db-wal` survives a clean shutdown. - The README caveat added by https://git.eeqj.de/sneak/webhooker/pulls/263 documenting this gap is reverted, since it will no longer be true. - Confirm the close path cannot block or panic if a writer is mid-write when the stop hook fires, and that it respects the existing stop-context budget rather than extending shutdown past it — https://git.eeqj.de/sneak/webhooker/issues/134 and https://git.eeqj.de/sneak/webhooker/issues/102 set that budget and must not regress. - Confirm a `kill -9` still leaves recoverable state — this makes the CLEAN path single-file, it must not make the unclean path worse. Not milestoned: no data is lost under the documented procedure, and the fix touches shutdown ordering, which is worth doing carefully rather than quickly.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/webhooker#280