Skip to content

store: write file stores atomically - #81

Closed
aberoham wants to merge 10 commits into
NicTool:mainfrom
aberoham:file-store-atomic-writes
Closed

aberoham wants to merge 10 commits into
NicTool:mainfrom
aberoham:file-store-atomic-writes

Conversation

@aberoham

@aberoham aberoham commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Builds on #70. Until #70 merges, the diff also shows its commits. The change here is the last commit, store: write file stores atomically.

The json and toml stores rewrite a whole file on every write. fs.writeFile truncates it first, so a load in the same api process can read half a file during a write. A json load then throws "Unexpected end of JSON input". A toml load can parse the half as fewer rows.

A write now goes to a temporary file beside the real one, with the old file's mode, and is renamed into place. A load sees either the old file or the new one. The store directory must be writable, not just its files.

A probe ran loads through repeated writes of 20,000 rows. Before this change, 319 of 482 json loads and 305 of 478 toml loads failed or came back short. None did after it.

A permission create loaded the user file, then saved it outside the
per-file lock, so users created meanwhile vanished.
authenticate() saved the user list it loaded before hashing, so users
created during a login's hash upgrade vanished.
put, delete and destroy saved a list they had loaded earlier, so rows
created in between vanished. They now change rows inside mutate(),
which skips the write when the callback returns false. Nothing writes
outside the lock, so save() and the _save helpers are gone.

A file without last_id now records its highest id before a change, so
destroying that row can't free its id for reuse. A permission with no
user or group fails on the file stores instead of storing nothing:
inline permission ids are user and group ids, so there is no free id.
A load during a write could read half a file and fail to parse. _write
now writes a copy with the old file's mode and renames it over the
file.
@aberoham
aberoham force-pushed the file-store-atomic-writes branch from 1642410 to 825fe1a Compare October 14, 2026 21:11
@aberoham

Copy link
Copy Markdown
Contributor Author

Folded into #70 as 33c1483.

@aberoham aberoham closed this Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant