From afd8ab4bfbc632f700386c37616a11be5a2514a1 Mon Sep 17 00:00:00 2001 From: Petr Date: Thu, 25 Jun 2026 21:49:22 +0200 Subject: [PATCH] fix: atomic writes for posts and users.toml Write to a .tmp file and then File.rename into place, so a concurrent read or a mid-write crash never sees a torn file. --- lib/volumen/store.rb | 4 +++- lib/volumen/users.rb | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/volumen/store.rb b/lib/volumen/store.rb index 4101302..67ebaf0 100644 --- a/lib/volumen/store.rb +++ b/lib/volumen/store.rb @@ -37,7 +37,9 @@ module Volumen def save(post) target = post.path || default_path_for(post) FileUtils.mkdir_p(File.dirname(target)) - File.write(target, post.to_file) + tmp = "#{target}.tmp" + File.write(tmp, post.to_file) + File.rename(tmp, target) post.path = target @all = nil post diff --git a/lib/volumen/users.rb b/lib/volumen/users.rb index ef261fa..78ee108 100644 --- a/lib/volumen/users.rb +++ b/lib/volumen/users.rb @@ -118,7 +118,9 @@ module Volumen def persist(users) FileUtils.mkdir_p(File.dirname(@path)) - File.write(@path, TomlRB.dump("users" => users.map { |user| user_hash(user) })) + tmp = "#{@path}.tmp" + File.write(tmp, TomlRB.dump("users" => users.map { |user| user_hash(user) })) + File.rename(tmp, @path) end def user_hash(user)