I'm trying to write an asyncio
script which may be gracefully shutdown by sending a SIGHUP signal.
import asyncio
from signal import SIGHUP
def handle_sighup():
print("sighup received")
raise Exception()
async def main():
asyncio.get_running_loop().add_signal_handler(SIGHUP, handle_sighup)
while True:
print("running")
await asyncio.sleep(1)
try:
asyncio.run(main())
finally:
asyncio.run(graceful_shutdown())
Naively I assumed raising an unhandled exception in the handler would propagate to the main coroutine and cause the finally
block to execute. However, after printing "sighup received" the main coroutine continues to run.
I guess the callback is being run in an executor?
How can I refactor this code so that a signal can be handled to cause the main coroutine to be stopped and execution to drop down to the finally
block? Is there a better approach?
You can use sys.exit in handle_sighup
import asyncio
import signal
import sys
def handle_sighup():
print("sighup received")
sys.exit(0)
async def graceful_shutdown():
await asyncio.sleep(0.5)
print("shutdown")
async def main():
asyncio.get_running_loop().add_signal_handler(signal.SIGHUP, handle_sighup)
while True:
print("running")
await asyncio.sleep(1)
try:
asyncio.run(main())
except SystemExit:
asyncio.run(graceful_shutdown())
# finally: # you can put it in finally instead of except, up to you
# asyncio.run(graceful_shutdown())
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.