LibBee / src /services /runtime_store.py
nikeshn's picture
Upload 6 files
37ae25d verified
Raw
History Blame Contribute Delete
1.71 kB
"""
runtime_store.py — LibBee v3.1
Fixes applied:
1. save() now uses atomic write-then-rename (os.replace) to prevent file
corruption on crash or mid-write failure.
os.replace is atomic on POSIX (Linux/macOS) and effectively atomic on
Windows (same filesystem). This protects feedback.jsonl, metrics.json,
and runtime_config.json from partial writes.
"""
import json
import os
import time
from pathlib import Path
from typing import Any, Dict, Optional
class JsonRuntimeStore:
def __init__(self, path: Path, default: Optional[Dict[str, Any]] = None):
self.path = Path(path)
self.path.parent.mkdir(parents=True, exist_ok=True)
self.default = default or {}
def load(self) -> Dict[str, Any]:
if not self.path.exists():
return dict(self.default)
try:
return json.loads(self.path.read_text(encoding="utf-8"))
except Exception:
return dict(self.default)
def save(self, data: Dict[str, Any]) -> None:
"""Atomically write data to disk using a temp file + os.replace."""
tmp = self.path.with_suffix(".tmp")
try:
tmp.write_text(
json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8"
)
os.replace(tmp, self.path)
except Exception:
try:
tmp.unlink(missing_ok=True)
except Exception:
pass
raise
def update(self, **kwargs: Any) -> Dict[str, Any]:
data = self.load()
data.update(kwargs)
data["updated_at"] = time.time()
self.save(data)
return data