Reload configuration on change.
authorBenjamin Braatz <bb@bbraatz.eu>
Wed, 30 Jun 2021 01:18:05 +0000 (03:18 +0200)
committerBenjamin Braatz <bb@bbraatz.eu>
Wed, 30 Jun 2021 01:18:05 +0000 (03:18 +0200)
controlpi/__main__.py
setup.py

index 046820e7ffdde3dd75811264b586108482e89ac5..848e9b26aa6c6aa4a5a27850ed0fdd3a929f8aaf 100644 (file)
@@ -6,17 +6,23 @@ started by:
 """
 import signal
 import sys
+import os
 import json
 import asyncio
+import pyinotify  # type: ignore
 
 from controlpi import run, PluginConf
 
 from typing import Dict
 
+restart = True
+
 
 async def shutdown(sig: signal.Signals) -> None:
     """Shutdown the system in reaction to a signal."""
+    global restart
     print(f"Shutting down on signal {sig.name}.")
+    restart = False
     for task in asyncio.all_tasks():
         if task is not asyncio.current_task():
             task.cancel()
@@ -45,11 +51,33 @@ def read_configuration() -> Dict[str, PluginConf]:
     return conf
 
 
+class ConfigChangeHandler(pyinotify.ProcessEvent):
+    def process_IN_MODIFY(self, event):
+        print("Configuration file modified.")
+        for task in asyncio.all_tasks():
+            if task is not asyncio.current_task():
+                task.cancel()
+
+
+async def add_config_change_handler() -> pyinotify.AsyncioNotifier:
+    wm = pyinotify.WatchManager()
+    loop = asyncio.get_running_loop()
+    notifier = pyinotify.AsyncioNotifier(wm, loop,
+                                         default_proc_fun=ConfigChangeHandler())
+    wm.add_watch(os.path.dirname(sys.argv[1]), pyinotify.ALL_EVENTS)
+    wm.add_watch(sys.argv[1], pyinotify.ALL_EVENTS)
+    return notifier
+
+
 async def main() -> None:
     """Set up signal handlers, read configuration file and run system."""
+    global restart
     await add_signal_handlers()
-    conf = read_configuration()
-    await run(conf)
+    notifier = await add_config_change_handler()
+    while restart:
+        conf = read_configuration()
+        await run(conf)
+    notifier.stop()
 
 if __name__ == '__main__':
     asyncio.run(main())
index 08f106f3cd3fb1438d6b525570e9df4676cfbc30..60fa604bc6e8a6d2f02798a284491bb327052d59 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -17,6 +17,7 @@ setuptools.setup(
     zip_safe=False,
     install_requires=[
         "jsonschema",
+        "pyinotify",
     ],
     extras_require={
         "dev": [