mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
refactor(pkg/utils): add unified atomic file write utility
This commit is contained in:
+8
-19
@@ -8,6 +8,8 @@ import (
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/sipeed/picoclaw/pkg/utils"
|
||||
)
|
||||
|
||||
// State represents the persistent state for a workspace.
|
||||
@@ -124,33 +126,20 @@ func (sm *Manager) GetTimestamp() time.Time {
|
||||
// saveAtomic performs an atomic save using temp file + rename.
|
||||
// This ensures that the state file is never corrupted:
|
||||
// 1. Write to a temp file
|
||||
// 2. Rename temp file to target (atomic on POSIX systems)
|
||||
// 3. If rename fails, cleanup the temp file
|
||||
// 2. Sync to disk (critical for SD cards/flash storage)
|
||||
// 3. Rename temp file to target (atomic on POSIX systems)
|
||||
// 4. If rename fails, cleanup the temp file
|
||||
//
|
||||
// Must be called with the lock held.
|
||||
func (sm *Manager) saveAtomic() error {
|
||||
// Create temp file in the same directory as the target
|
||||
tempFile := sm.stateFile + ".tmp"
|
||||
|
||||
// Marshal state to JSON
|
||||
// Use unified atomic write utility with explicit sync for flash storage reliability.
|
||||
// Using 0o600 (owner read/write only) for secure default permissions.
|
||||
data, err := json.MarshalIndent(sm.state, "", " ")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal state: %w", err)
|
||||
}
|
||||
|
||||
// Write to temp file
|
||||
if err := os.WriteFile(tempFile, data, 0o644); err != nil {
|
||||
return fmt.Errorf("failed to write temp file: %w", err)
|
||||
}
|
||||
|
||||
// Atomic rename from temp to target
|
||||
if err := os.Rename(tempFile, sm.stateFile); err != nil {
|
||||
// Cleanup temp file if rename fails
|
||||
os.Remove(tempFile)
|
||||
return fmt.Errorf("failed to rename temp file: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
return utils.WriteFileAtomic(sm.stateFile, data, 0o600)
|
||||
}
|
||||
|
||||
// load loads the state from disk.
|
||||
|
||||
Reference in New Issue
Block a user