简体   繁体   中英

Graceful shutdown and signal handling

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM