Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
daemon: Switch signal handling to event loop
Now that we're using asyncio we need to use its signal handling functions so we don't confuse it. One symptom is that server shutdown will hang indefinitely if triggered from a signal.signal signal handler. So we switch to asyncio.loop.add_signal_handler() which is mostly a drop-in replacement. Handler routines are normal functions and cannot even be coroutines, so no problem there. Signal handlers have no default or standard parameters any more so we need to pass the signal number explicitly if we want to be able to distringuish them. One potential area of concern is registering the signal handlers with the correct event loop. Normally we'd pass the one we used for signal handlers explicitly to all other components using asyncio. Unfortunately, sanic does not allow that in the case of sanic.app.create_server(). But fortunately, it calls asyncio.get_event_loop() itself which yields the same global event loop as long as no-one goes around and starts creating new loops. This even works with sanic's behaviour up to and including version 21.9.3 of unconditionally switching the default asyncio event loop implementation to uvloop as it seems to happen early enough (on import sanic in server) so that our first call to get_event_loop() in the daemo also yields the uvloop loop eventually employed by sanic to create the server. So we now silently use uvloop with sanic up to and including 21.9.3 and standard asyncio with sanic 22.12.0 and later. Incidentally, the whole isssue became apparent only because with 22.12.0 shutdown would no longer work because python stdlib asyncio doesn't react well to signal.signal handling signals while with uvloop it works fine.
- Loading branch information