From 68f9007ef0fe0c5a06c267e19f7565b5a0b3d283 Mon Sep 17 00:00:00 2001 From: curo1305 Date: Tue, 19 May 2026 15:52:11 +0200 Subject: [PATCH] fix(daemon): install signal handlers inside running event loop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _install_signal_handlers() was called before asyncio.run(), registering handlers on a throwaway loop that asyncio.get_event_loop() created — so SIGTERM would never reach the supervisor. Move the call into _run_daemon() and switch to asyncio.get_running_loop() so handlers are registered on the actual running loop. Co-Authored-By: Claude Sonnet 4.6 --- src/pyra/daemon/core.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pyra/daemon/core.py b/src/pyra/daemon/core.py index ae8115d..894ea6f 100644 --- a/src/pyra/daemon/core.py +++ b/src/pyra/daemon/core.py @@ -144,6 +144,9 @@ def _make_ipc_handler(supervisor: PluginSupervisor): async def _run_daemon(cfg, supervisor: PluginSupervisor) -> None: from pyra.daemon.ipc import IpcServer, get_socket_path, is_unix_socket + # Install signal handlers now that the event loop is running. + _install_signal_handlers(supervisor) + if is_unix_socket(): address = get_socket_path(cfg.daemon.socket_path) else: @@ -194,7 +197,6 @@ def run_foreground() -> None: _start_time = time.monotonic() with pid_file: - _install_signal_handlers(supervisor) _log.info("Pyra daemon starting (PID %d).", os.getpid()) try: asyncio.run(_run_daemon(cfg, supervisor)) @@ -266,7 +268,7 @@ def _install_signal_handlers(supervisor: PluginSupervisor) -> None: signal.signal(signal.SIGTERM, lambda *_: supervisor.request_shutdown()) return - loop = asyncio.get_event_loop() + loop = asyncio.get_running_loop() loop.add_signal_handler(signal.SIGTERM, supervisor.request_shutdown) loop.add_signal_handler(signal.SIGHUP, supervisor.request_shutdown)