MagicStack / MagicStack/uvloop
Application hanging after KeyboardInterrupt
Nessuno ha ancora preso questa issue.
- Lingua principale
- Cython
- Stelle
- 11.9k
- Fork
- 616
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Descrizione
- uvloop version: 0.14.0
- Python version: 3.7.4
- Platform: Manjaro
- Can you reproduce the bug with
PYTHONASYNCIODEBUGin env?: Yes - Does uvloop behave differently from vanilla asyncio? How?: With vanilla, the application terminates gracefully upon reception of a keyboard interrupt. If I use
uvloop, I get a runtime warning and the application hangs until I run akill -9on the process id.
Snippet: issue.py
import asyncio
from asyncio import AbstractEventLoop
import os
from typing import Union, Type
import uvloop # type: ignore
from aiohttp import web
import signal
import aiologger
logger = aiologger.Logger.with_default_handlers()
async def handle_exception(loop: AbstractEventLoop, context):
# context["message"] will always be there; but context["exception"] may not
msg = context.get("exception", context["message"])
await logger.error(f"Caught exception: {msg}")
await logger.info("Shutting down...")
asyncio.create_task(shutdown(loop))
async def shutdown(loop: AbstractEventLoop, signal=None):
"""Cleanup tasks tied to the service's shutdown."""
if signal:
await logger.info(f"Received exit signal {signal.name}...")
tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()]
[task.cancel() for task in tasks]
await logger.info(f"Cancelling {len(tasks)} outstanding tasks")
await asyncio.gather(*tasks, return_exceptions=True)
loop.stop()
async def start(
app: web.Application, host: str, port: Union[str, int]
) -> web.AppRunner:
"""Start the server"""
runner = web.AppRunner(app)
await runner.setup()
server = web.TCPSite(runner, host, int(port))
await server.start()
return runner
def main() -> None:
"""Entrypoint"""
host = os.environ.get("HOST", "localhost")
port = os.environ.get("PORT", 8000)
app = web.Application()
loop = asyncio.get_event_loop()
signals = (signal.SIGHUP, signal.SIGTERM, signal.SIGINT)
for s in signals:
loop.add_signal_handler(
s, lambda s=s: asyncio.create_task(shutdown(loop, signal=s))
)
loop.set_exception_handler(handle_exception)
print(
f"======== Running on http://{host}:{port} ========\n" "(Press CTRL+C to quit)"
)
try:
runner = loop.run_until_complete(start(app, host, port))
loop.run_forever()
finally:
loop.run_until_complete(runner.cleanup())
loop.close()
if __name__ == "__main__":
uvloop.install()
main()
Run the file:
python issue.py
Then hit Ctrl+c on keyboard, output:
======== Running on http://0.0.0.0:8000 ========
(Press CTRL+C to quit)
^Cissue.py:70: RuntimeWarning: coroutine 'handle_exception' was never awaited
Coroutine created at (most recent call last)
File "issue.py", line 78, in <module>
main()
File "issue.py", line 70, in main
loop.run_forever()
loop.run_forever()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Which hangs until running kill -9 <pid>
If you comment out uvloop.install() and follow the same steps, the program terminates as expected. Output:
======== Running on http://0.0.0.0:8000 ========
(Press CTRL+C to quit)
^CReceived exit signal SIGINT...
Cancelling 0 outstanding tasks
Guida per i contributori
Nessuna guida per i contributori indicizzata per questo repository
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia eseguendo issue.py con uvloop 0.14.0, Python 3.7.4 e PYTHONASYNCIODEBUG abilitato, quindi confronta il comportamento con Ctrl+C con quello di vanilla asyncio. Analizza la gestione delle eccezioni del ciclo degli eventi e il percorso di arresto tramite segnale mostrati nello snippet. Il lavoro è completato quando KeyboardInterrupt attiva una pulizia corretta senza l’avviso relativo a una coroutine non attesa né un processo bloccato.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- python
- Ambito
- backend
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Ferma
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 38/100