Skip to content

Commit 8cdce62

Browse files
marcelveldtagners
andauthored
Use atomic writes for the storage file (#1014)
Co-authored-by: Stefan Agner <stefan@agner.ch>
1 parent 380cfef commit 8cdce62

File tree

2 files changed

+10
-3
lines changed

2 files changed

+10
-3
lines changed

matter_server/server/storage.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55
import asyncio
66
import logging
77
from pathlib import Path
8+
import shutil
89
from typing import TYPE_CHECKING, Any, cast
910

11+
from atomicwrites import atomic_write
12+
1013
from ..common.helpers.json import JSON_DECODE_EXCEPTIONS, json_dumps, json_loads
1114

1215
if TYPE_CHECKING:
@@ -152,11 +155,14 @@ async def async_save(self) -> None:
152155

153156
def do_save() -> None:
154157
# make backup before we write a new file
155-
if self.filename.is_file():
156-
self.filename.replace(self.filename_backup)
158+
self.filename_backup.unlink(True)
159+
shutil.copy(self.filename, self.filename_backup)
157160

158-
with open(self.filename, "w", encoding="utf-8") as _file:
161+
# use atomomic write to avoid corrupting the file
162+
# if power is cut during write, we don't write a corrupted file
163+
with atomic_write(self.filename, encoding="utf-8", overwrite=True) as _file:
159164
_file.write(json_dumps(self._data))
165+
160166
LOGGER.debug("Saved data to persistent storage")
161167

162168
async with self._save_lock:

pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ server = [
3535
"aiohttp==3.11.11",
3636
"aiorun==2024.8.1",
3737
"async-timeout==5.0.1",
38+
"atomicwrites==1.4.1",
3839
"coloredlogs==15.0.1",
3940
"cryptography==44.0.0",
4041
"orjson==3.10.12",

0 commit comments

Comments
 (0)