feat: add config read-modify-write update and harden file watcher

Config.update_config() applies submitted options to the main
configuration file via configparser read-modify-write: unknown
options are preserved, null removes an option, the merged view
of all files is validated as ServerConfig before anything is
written (a bad file would kill the FileWatcher polling loop),
and the write is atomic (.tmp + os.replace, mode 0600). Options
whose effective value is owned by a later configuration file
raise ConfigConflictError instead of writing a no-op. The
reload logic is factored into reload_and_notify() and the file
watcher callback is exception-guarded so polling never dies.
This commit is contained in:
YueGuobin committed 2026-08-23 18:54:23 +08:00
1 parent d3ceb453a6
commit 7d3cbf1023
5 files changed
+282 -7

No files matched your search

+10 -1
View File
@@ -19,6 +19,10 @@ import zlib
import asyncio
import os
import logging
log = logging.getLogger(__name__)
class FileWatcher:
"""
@@ -98,7 +102,12 @@ class FileWatcher:
except OSError:
self._hashed[path] = None
if changed:
self._callback(path)
try:
self._callback(path)
except Exception:
# never let a callback exception kill the polling loop
# (the re-schedule below must always run)
log.exception(f"Error in file watcher callback for '{path}'")
asyncio.get_event_loop().call_later(self._delay, self._check_config_file_change)
@property