How to handle graceful shutdown inside of aiohttp coroutines?

Viewed 186

I want to save state into the database of a background aiohttp coroutine before server is shut down. I was thinking of creating a global array of coroutine jobs that need to be finished and do an await asyncio.gather(*global_jobs) in the shutdown handler.

Is this the proper approach?

1 Answers

I'm not sure I understand what you mean by "the database of a background aiohttp coroutine" but, as far as cleanup actions at shutdown go, you can:

Use a signal handler

import asyncio
import signal


loop = asyncio.get_event_loop()
loop.add_signal_handler(signal.SIGINT, my_signal_handler, *additional_args_list)

In a Unix setting, if you know that the application is going to be interrupted with a specific signal, you can perform cleanup actions selectively for that signal. See loop.add_signal_handler(signum, callback, *args) for further information.

Note: you can employ a callable class rather than a function as callback, so that the class instance can hold a reference to any resource you wish to interact with during shutdown, e.g. the coroutines you mentioned in your question.

Catch asyncio.CancelledError

import asyncio


async def my_coro():
    try:
        # Normal interaction with aiohttp
        while True:
            pass
    except asyncio.CancelledError:
        cleanup_actions()

If you can assume that, at shutdown, the event loop will be stopped cleanly, you can count on your running coroutines to be thrown an asyncio.CancelledError before the loop is closed.

Related