Scope the PID lock to mutating commands (closes #150)
check / check (pull_request) Successful in 1m21s

RunWithApp took the process-wide PID lock for every fx-backed command,
so read-only commands (info, snapshot list, snapshot verify, remote
info) failed with "already running" while a backup held it.

AppOptions now carries a lockMode, and each command declares its mode at
the call site. Only mutating commands (snapshot create, snapshot purge,
snapshot remove, prune, remote nuke) acquire the lock; read-only ones run
without it and are never blocked. snapshot restore is classified
read-only: it writes only to its target directory, not the local index
or remote store. The acquire/skip decision moves to a small
acquireLockIfMutating helper, covered by a test that a read-only command
runs while the lock is held and two mutators still exclude. The README
locking section is rewritten to match.

Model: opus-4-8
This commit is contained in:
2026-09-22 08:42:57 +00:00
parent 38ebfd843a
commit 782cd17076
8 changed files with 127 additions and 38 deletions
+12 -10
View File
@@ -171,18 +171,20 @@ vaultik version
### locking
Every command that opens the local index`snapshot create`, `snapshot
list`, `snapshot verify`, `snapshot purge`, `snapshot remove`, `snapshot
restore`, `prune`, `info`, and `remote info`/`remote nuke` — takes a
Commands that write persistent state`snapshot create`, `snapshot
purge`, `snapshot remove`, `prune`, and `remote nuke` — take a
process-wide lock at `$XDG_DATA_HOME/vaultik/vaultik.pid`
(`~/.local/share/vaultik/vaultik.pid` on Linux) for the whole run. Only
one such command runs at a time: a second one exits immediately with an
"already running" error rather than waiting. The lock is not scoped to
mutating commands, so read-only commands are affected too — `vaultik
snapshot list` fails while a backup is in progress; scoping it so
read-only commands run during a backup is tracked in
[issue #150](https://git.eeqj.de/sneak/vaultik/issues/150). `config`,
`database delete`, `completion`, and `version` do not take the lock.
one of them runs at a time: a second one exits immediately with an
"already running" error rather than waiting, so two writers can never
corrupt the local index or the destination store.
Read-only commands `info`, `snapshot list`, `snapshot verify`, and
`remote info` — do not take the lock and are never blocked, so they run
even while a backup is in progress. `snapshot restore` does not take the
lock either: it writes only to the target directory you name, not the
local index or the destination store. `config`, `database delete`,
`completion`, and `version` do not take the lock.
### stdout and stderr