refactor: extract write_json_atomic helper, DRY 8 call sites
Move the crash-safe write-then-rename pattern into zesdex-utils::write_json_atomic and apply it across: - zesdex-cms: app_config_repo, conversation_repo, settings_repo - zesdex-iam: oauth_repo, session_repo - zesdex-entities: Conversation::save_conversation, Session::save Excluded (non-JSON format): - rewind_blob_repo (binary blob) - memory_repo (markdown + frontmatter, not JSON) - session_lock (PID string, not JSON) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
9a6ab62562
commit
4cd38c9291
@@ -11,6 +11,8 @@
|
||||
//! 0o600 on Unix.
|
||||
use std::path::Path;
|
||||
|
||||
use zesdex_utils::write_json_atomic;
|
||||
|
||||
use crate::domain::oauth::OAuthToken;
|
||||
use crate::domain::repository::OAuthRepository;
|
||||
|
||||
@@ -30,20 +32,7 @@ impl OAuthRepository for FileSystemOAuthRepository {
|
||||
if let Some(parent) = path.parent() {
|
||||
std::fs::create_dir_all(parent)?;
|
||||
}
|
||||
let data = serde_json::to_string_pretty(token)?;
|
||||
let tmp = path.with_extension("tmp");
|
||||
std::fs::write(&tmp, data)?;
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
std::fs::set_permissions(&tmp, std::fs::Permissions::from_mode(0o600))?;
|
||||
}
|
||||
let f = std::fs::File::open(&tmp)?;
|
||||
f.sync_all()?;
|
||||
std::fs::rename(&tmp, path)?;
|
||||
if let Some(parent) = path.parent() {
|
||||
let _ = std::fs::File::open(parent).and_then(|d| d.sync_all());
|
||||
}
|
||||
write_json_atomic(path, token, Some(0o600))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
//! Writes use a write-then-rename + fsync pattern for crash safety.
|
||||
use std::path::Path;
|
||||
|
||||
use zesdex_utils::write_json_atomic;
|
||||
|
||||
use crate::domain::repository::SessionRepository;
|
||||
use crate::domain::session::Session;
|
||||
|
||||
@@ -61,17 +63,7 @@ impl SessionRepository for FileSystemSessionRepository {
|
||||
let dir = session.session_dir(base_dir);
|
||||
std::fs::create_dir_all(&dir)?;
|
||||
let path = dir.join("session.json");
|
||||
let data = serde_json::to_string_pretty(session)?;
|
||||
let tmp = dir.join("session.json.tmp");
|
||||
std::fs::write(&tmp, data)?;
|
||||
// fsync before rename ensures the data is on disk.
|
||||
let f = std::fs::File::open(&tmp)?;
|
||||
f.sync_all()?;
|
||||
std::fs::rename(&tmp, path)?;
|
||||
// fsync the parent directory so the rename survives a crash.
|
||||
if let Some(parent) = dir.parent() {
|
||||
let _ = std::fs::File::open(parent).and_then(|d| d.sync_all());
|
||||
}
|
||||
write_json_atomic(&path, session, None)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user