web.run_app(): Terminate properly with signal TERM and INT #1932
Description
Long story short
This is more or less related to #63. My issue is that web.run_app() gracefully exit when SIGINT is sent to the process but not when SIGTERM is sent.
This is because web.run_app() catches SIGINT (with KeyboardInterrupt exception) but does not override SIGTERM handling (there is no exception raised for that, one can only use signal.signal). Most of the time it is SIGTERM that is used to gracefully shutdown a process but that will actually kill the application instead of letting the requests finish properly and response. kill, Docker and system.d use SIGTERM by default.
Expected behaviour
I suppose the default expected behavior of web.run_app() is to allow the requests to be finished before terminating the process. That's what most people would think it does. The feeling is also harder since it does it already for SIGINT.
Actual behaviour
Only SIGINT triggers a graceful exit. SIGTERM does not let the running requests finish.
Steps to reproduce
- run this script
import asyncio
from aiohttp import web
async def handle(request):
await asyncio.sleep(60)
text = "Hello"
return web.Response(text=text)
app = web.Application()
app.router.add_get('/', handle)
web.run_app(app)
- do a GET request on /
- send SIGTERM to the process
- you will notice the process ends before the 60 seconds and your request has been canceled
Your environment
Python 3.6, Arch Linux