fix: atomic writes for manifest/record_run/update_best (tmp+replace)

This commit is contained in:
2026-07-16 05:34:45 -04:00
parent d1516bf56b
commit 96884dd149
2 changed files with 46 additions and 6 deletions
+19 -6
View File
@@ -64,6 +64,21 @@ def _now_iso() -> str:
return datetime.now(UTC).isoformat()
def _atomic_write_json(path: Path, data: dict) -> None:
"""原子写 JSONtmp + os.replace(对齐 checkpoint.py 范式,防半截损坏)。
先写同目录临时文件,再 os.replace 原子替换目标;替换阶段崩溃不会留下半截
JSON,原文件保持完好。
参数:
path: 目标 JSON 文件路径。
data: 待序列化的字典。
"""
tmp = path.with_name(path.name + ".tmp")
tmp.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
os.replace(tmp, path)
# ---------------------------------------------------------------------------
# Workspace 核心函数
# ---------------------------------------------------------------------------
@@ -108,7 +123,7 @@ def _scaffold_workspace(
},
"history": [],
}
(workspace_dir / "manifest.json").write_text(json.dumps(manifest, ensure_ascii=False, indent=2))
_atomic_write_json(workspace_dir / "manifest.json", manifest)
def init_workspace(
@@ -286,7 +301,7 @@ def update_manifest(workspace_dir: Path, **version_updates: str) -> None:
raise KeyError(f"无效的 manifest current 字段: {invalid}")
manifest = load_manifest(workspace_dir)
manifest["current"].update(version_updates)
(workspace_dir / "manifest.json").write_text(json.dumps(manifest, ensure_ascii=False, indent=2))
_atomic_write_json(workspace_dir / "manifest.json", manifest)
def record_run(workspace_dir: Path, run_id: str) -> Path:
@@ -315,9 +330,7 @@ def record_run(workspace_dir: Path, run_id: str) -> Path:
"questions": current["questions"],
}
)
(workspace_dir / "manifest.json").write_text(
json.dumps(manifest, ensure_ascii=False, indent=2)
)
_atomic_write_json(workspace_dir / "manifest.json", manifest)
run_dir = workspace_dir / "runs" / run_id
# exist_ok:同 run_id 重跑时 run 目录已存在不应崩溃
@@ -369,7 +382,7 @@ def update_best(
"run_id": run_id,
"epoch": epoch,
}
(workspace_dir / "manifest.json").write_text(json.dumps(manifest, ensure_ascii=False, indent=2))
_atomic_write_json(workspace_dir / "manifest.json", manifest)
logger.info("Best 已更新: val_acc={}, run={}, epoch={}", val_acc, run_id, epoch)