Fix _save_state race condition losing last_reflection timestamp
Daily and weekly timers fired simultaneously on Sundays, causing decay() and reflect() to race on _state.json. Now merges top-level keys before writing and uses atomic tempfile+rename to prevent partial reads from triggering silent JSONDecodeError fallbacks. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
25792a74f4
commit
7f120f8c5c
@ -622,9 +622,30 @@ class CognitiveMemoryClient:
|
|||||||
return {"version": 1, "updated": "", "entries": {}}
|
return {"version": 1, "updated": "", "entries": {}}
|
||||||
|
|
||||||
def _save_state(self, state: Dict):
|
def _save_state(self, state: Dict):
|
||||||
"""Write _state.json."""
|
"""Write _state.json atomically, merging top-level keys to prevent race conditions."""
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
# Merge with existing state to preserve keys written by concurrent processes
|
||||||
|
if self.state_path.exists():
|
||||||
|
try:
|
||||||
|
existing = json.loads(self.state_path.read_text())
|
||||||
|
existing.update(state)
|
||||||
|
state = existing
|
||||||
|
except (json.JSONDecodeError, OSError):
|
||||||
|
pass
|
||||||
state["updated"] = datetime.now(timezone.utc).isoformat()
|
state["updated"] = datetime.now(timezone.utc).isoformat()
|
||||||
self.state_path.write_text(json.dumps(state, indent=2, default=str))
|
# Atomic write: write to temp file then rename
|
||||||
|
fd, tmp_path = tempfile.mkstemp(dir=self.memory_dir, suffix=".tmp")
|
||||||
|
try:
|
||||||
|
with os.fdopen(fd, "w") as f:
|
||||||
|
json.dump(state, f, indent=2, default=str)
|
||||||
|
os.replace(tmp_path, self.state_path)
|
||||||
|
except Exception:
|
||||||
|
try:
|
||||||
|
os.unlink(tmp_path)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
raise
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
# File I/O
|
# File I/O
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user