host: real-backup
This commit is contained in:
1 parent
d1e842b90f
commit
5731675153
1 file changed
+18
-2
@@ -326,7 +326,8 @@ def _state_lock(path, exclusive=True):
|
|||||||
def _read_state_file(path):
|
def _read_state_file(path):
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
try:
|
try:
|
||||||
return json.load(open(path))
|
with open(path) as f:
|
||||||
|
return json.load(f)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
return {"tasks": {}, "automations": []}
|
return {"tasks": {}, "automations": []}
|
||||||
@@ -356,7 +357,22 @@ def save_state(path, state):
|
|||||||
if k not in ("tasks", "automations"):
|
if k not in ("tasks", "automations"):
|
||||||
merged[k] = v
|
merged[k] = v
|
||||||
tmp = f"{path}.tmp.{os.getpid()}"
|
tmp = f"{path}.tmp.{os.getpid()}"
|
||||||
json.dump(merged, open(tmp, "w"), indent=2, ensure_ascii=False)
|
with open(tmp, "w") as f:
|
||||||
|
json.dump(merged, f, indent=2, ensure_ascii=False)
|
||||||
|
if os.path.exists(path):
|
||||||
|
import shutil
|
||||||
|
backup = path + ".bak"
|
||||||
|
backup_1 = backup + ".1"
|
||||||
|
backup_2 = backup + ".2"
|
||||||
|
backup_tmp = f"{backup}.tmp.{os.getpid()}.{threading.get_ident()}"
|
||||||
|
shutil.copy2(path, backup_tmp)
|
||||||
|
if os.path.exists(backup_2):
|
||||||
|
os.remove(backup_2)
|
||||||
|
if os.path.exists(backup_1):
|
||||||
|
os.replace(backup_1, backup_2)
|
||||||
|
if os.path.exists(backup):
|
||||||
|
os.replace(backup, backup_1)
|
||||||
|
os.replace(backup_tmp, backup)
|
||||||
os.replace(tmp, path)
|
os.replace(tmp, path)
|
||||||
# 让调用方内存里的 state 也跟上合并结果,避免下次保存
|
# 让调用方内存里的 state 也跟上合并结果,避免下次保存
|
||||||
# 又把别的进程的任务挤掉(调用方继续用这份 state 时)。
|
# 又把别的进程的任务挤掉(调用方继续用这份 state 时)。
|
||||||
|
|||||||
Reference in new issue
Block a user