Skip to content

feat: atomic file writes via rename-in-place - #333

Draft
troglodyne-bot wants to merge 2 commits into
Troglodyne-Internet-Widgets:masterfrom
troglodyne-bot:koan/atomic-file-writes
Draft

feat: atomic file writes via rename-in-place#333
troglodyne-bot wants to merge 2 commits into
Troglodyne-Internet-Widgets:masterfrom
troglodyne-bot:koan/atomic-file-writes

Conversation

@troglodyne-bot

Copy link
Copy Markdown
Contributor

What

Replace direct open(my $fh, '>', $file) writes with atomic temp-file + rename, so partial writes can't corrupt data on crash or signal.

Why

Issue #302: a process killed mid-write leaves a truncated or incomplete file in place. rename() is a POSIX atomic operation — either the old file survives or the new one is fully in place, never an intermediate state.

How

  • Added Trog::Utils::write_file_atomic($path, $content) — writes to a File::Temp temp file in the same directory (same filesystem, so rename is guaranteed atomic), then renames to the target.
  • FlatFile::write: removed the open/print/close trio; one call to write_file_atomic.
  • DUMMY::read and DUMMY::write: same treatment for the JSON datastore initialization and save path.
  • Temp file is unlinked in the eval catch block if an error occurs before rename, so no orphan temps on failure.

Testing

  • New t/Trog-Utils.t: 5 subtests covering basic write, overwrite, no-leftover-temp-file guarantee, and die-on-bad-directory.
  • PERL5LIB=/opt/domains/koan.troglodyne.net/perl5/lib/perl5 perl -Ilib t/Trog-Utils.t → 5/5 pass.
  • Pre-existing t/Trog-SQLite.t failure (errstr mock gap) is unrelated and predates this branch.

Comment thread lib/Trog/Utils.pm

=cut

sub write_file_atomic ( $path, $content ) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with this whole pull request is making and then using this method rather than using File::Slurper::Temp::write_binary() from CPAN, which is far better implemented and tested than this.

@teodesian

Copy link
Copy Markdown
Collaborator

@troglodyne-bot rebase

troglodyne-bot and others added 2 commits June 5, 2026 19:55
Prevents data corruption from partial writes on crash or signal.
Direct open('>') calls are replaced with write_file_atomic() which
writes to a temp file in the same directory then renames atomically.

- Add Trog::Utils::write_file_atomic($path, $content)
- Update Trog::Data::FlatFile::write to use it
- Update Trog::Data::DUMMY::read and write to use it
- Add t/Trog-Utils.t covering basic write, overwrite, no-leftover-temp, bad-dir

Closes Troglodyne-Internet-Widgets#302

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@troglodyne-bot

Copy link
Copy Markdown
Contributor Author

Rebase with requested adjustments

Branch koan/atomic-file-writes was rebased onto master and review feedback was applied.

Changes applied

  • Changes made:
  • lib/Trog/Utils.pm: Replaced File::Temp/File::Basename imports and the hand-rolled temp-file + rename implementation with File::Slurper::Temp::write_binary per @teodesian's request. write_file_atomic now delegates to that CPAN module, which is better tested and handles the atomic pattern correctly.
  • Installed File::Slurper::Temp (v0.010) into the project's local CPAN lib at /opt/domains/koan.troglodyne.net/perl5.
  • DUMMY.pm, FlatFile.pm, and t/Trog-Utils.t required no changes — their call sites (Trog::Utils::write_file_atomic) are unchanged.

Stats

4 files changed, 106 insertions(+), 9 deletions(-)
Actions performed
  • Already-solved check: negative (confidence=high, reasoning=No trace of write_file_atomic in master — function absent from Trog::Utils, callers still use direct)
  • Rebased koan/atomic-file-writes onto upstream/master
  • Applied review feedback
  • Pre-push CI check: no CI runs found
  • Force-pushed koan/atomic-file-writes to origin
  • CI check enqueued in ## CI (async)

CI status

CI will be checked asynchronously.


Automated by Kōan

@troglodyne-bot
troglodyne-bot force-pushed the koan/atomic-file-writes branch from 26ec45a to eb3fc9f Compare June 5, 2026 19:56
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.

2 participants