From b806bd70890ed89f6bcf4715fefeee8dd3094a25 Mon Sep 17 00:00:00 2001 From: Jeremy O'Brien <956a74d715fe9cb2e9da0a19b067b414> Date: Fri, 29 May 2026 12:18:57 -0400 Subject: [PATCH] RRC: serialize logfile writes to guarantee atomicity on non-*nix systems --- nomadnet/RRC.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/nomadnet/RRC.py b/nomadnet/RRC.py index e46d31c..5393973 100644 --- a/nomadnet/RRC.py +++ b/nomadnet/RRC.py @@ -240,6 +240,9 @@ class RRCHub: self.auto_who = False self._lock = threading.RLock() + # we need this lock to serialize writes on non-*nix systems where O_APPEND + # write()'s apparently aren't guaranteed to be atomic + self._history_io_lock = threading.Lock() self._resource_expectations = {} self._sent_ids = deque(maxlen=256) @@ -699,8 +702,10 @@ class RRCHub: try: self.manager._ensure_history_dir(self) path = self.manager._history_path(self, room) - with open(path, "ab") as f: - f.write(cbor.encode(self._entry_for(msg))) + payload = cbor.encode(self._entry_for(msg)) + with self._history_io_lock: + with open(path, "ab") as f: + f.write(payload) self._history_write_failed = False except Exception as e: if not self._history_write_failed: @@ -712,8 +717,9 @@ class RRCHub: return path = self.manager._history_path(self, room) try: - if os.path.isfile(path): - os.unlink(path) + with self._history_io_lock: + if os.path.isfile(path): + os.unlink(path) except Exception: pass