0

I'm trying to implement a graceful shutdown to my web server ran by aiohttp. I need it to gracefully close and clean redis and DB connections.

For what I ve seen in the different documents talking about this I ve registered a callback with add_signal_handler of the main loop and yet the callbacks are still not triggered when my server shuts down.

Here is what I got:

def gracefull_shutdown(signame, loop):
   logging.debug('graceful shutdown callback')

app = web.Application()

if __name__ == '__main__':
   asyncioLoop = asyncio.get_event_loop()
   for signame in {'SIGINT', 'SIGTERM'}:
       asyncioLoop.add_signal_handler(
           getattr(signal, signame),
           functools.partial(gracefull_shutdown, signame, asyncioLoop)
           )

   web.run_app(app, handle_signals=True)

Do you have any idea ? thanks for your answers in advance

R.E.B Hernandez
  • 147
  • 2
  • 9

2 Answers2

1

Ok the solution is explained in the official docs but not easy to find. You can register callbacks through the property on_shutdown of the web application object.

https://docs.aiohttp.org/en/stable/web_advanced.html#aiohttp-web-graceful-shutdown

R.E.B Hernandez
  • 147
  • 2
  • 9
0
import asyncio
import functools
import weakref

from aiohttp import web
from aiohttp.web import Request, Response

routes = web.RouteTableDef()

def shutdown_aware(func):
    @functools.wraps(func)
    async def wrapper(request: Request):
        events: weakref.WeakSet[asyncio.Event] = request.app['shutdown_events']
        event = asyncio.Event()
        events.add(event)

        try:
            return await func(request)
        finally:
            event.set()
            events.discard(event)

    return wrapper

@routes.post('/hello/world')
@shutdown_aware
async def hello_world(request: Request) -> Response:
    # ...

async def on_shutdown(app: web.Application) -> None:
    events: weakref.WeakSet[asyncio.Event] = app['shutdown_events']

    for event in set(events):
        await event.wait()

if __name__ == '__main__':
    app = web.Application()
    app['shutdown_events'] = weakref.WeakSet()
    app.add_routes(routes)
    app.on_shutdown.append(on_shutdown)
    web.run_app(app, handle_signals=True)
Androbin
  • 991
  • 10
  • 27