Skip to content

web.run_app(): Terminate properly with signal TERM and INT #1932

Closed
@cecton

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

  1. 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)
  1. do a GET request on /
  2. send SIGTERM to the process
  3. you will notice the process ends before the 60 seconds and your request has been canceled

Your environment

Python 3.6, Arch Linux

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions