This commit is contained in:
2026-09-12 16:25:34 +08:00
parent 7a7049ce44
commit 554dd0f4cb
13 changed files with 646 additions and 93 deletions

View File

@@ -2,6 +2,9 @@
from os import PathLike
from pathlib import Path
import json
import os
from tempfile import NamedTemporaryFile
def is_lock(file_path: str | PathLike[str]) -> bool:
@@ -14,3 +17,32 @@ def write_lockfile(file_path: str | PathLike[str]) -> None:
path = Path(file_path)
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("LOCK", encoding="utf-8")
def claim_json(path: Path, record: dict) -> bool:
"""原子占位并落盘,成功后才允许提交;异常留下记录等待核对。"""
path.parent.mkdir(parents=True, exist_ok=True)
try:
stream = path.open('x', encoding='utf-8')
except FileExistsError:
return False
with stream:
json.dump(record, stream, ensure_ascii=False)
stream.flush()
os.fsync(stream.fileno())
return True
def replace_json(path: Path, record: dict) -> None:
"""原子替换核对结果,避免其他任务读取到半条记录。"""
temporary = None
try:
with NamedTemporaryFile(mode='w', encoding='utf-8', dir=path.parent, delete=False) as stream:
temporary = Path(stream.name)
json.dump(record, stream, ensure_ascii=False)
stream.flush()
os.fsync(stream.fileno())
os.replace(temporary, path)
finally:
if temporary is not None:
temporary.unlink(missing_ok=True)