Fix Ctrl+C on Windows.

This commit is contained in:
L. Kärkkäinen 2020-03-18 07:24:24 -07:00
parent 60b4efad67
commit 33388e6ae6
2 changed files with 31 additions and 10 deletions

View File

@ -1,3 +1,6 @@
import asyncio
import signal
from sys import argv
from multidict import CIMultiDict # type: ignore
@ -23,3 +26,25 @@ else:
async def open_async(file, mode="r", **kwargs):
return aio_open(file, mode, **kwargs)
def ctrlc_workaround_for_windows(app):
async def stay_active(app):
"""Frequently poll asyncio to allow *receiving* any signals in Python"""
while not die:
# If someone else stopped the app, just exit
if asyncio.get_running_loop()._stopping:
return
await asyncio.sleep(0.1)
# Can't be called from signal handler, so call it from here
app.stop()
def ctrlc_handler(sig, frame):
nonlocal die
if die:
raise KeyboardInterrupt("Non-graceful Ctrl+C")
die = True
die = False
signal.signal(signal.SIGINT, ctrlc_handler)
app.add_task(stay_active)

View File

@ -15,7 +15,7 @@ from time import time
from httptools import HttpRequestParser # type: ignore
from httptools.parser.errors import HttpParserError # type: ignore
from sanic.compat import Header
from sanic.compat import Header, ctrlc_workaround_for_windows
from sanic.exceptions import (
HeaderExpectationFailed,
InvalidUsage,
@ -929,15 +929,11 @@ def serve(
# Register signals for graceful termination
if register_sys_signals:
_singals = (SIGTERM,) if run_multiple else (SIGINT, SIGTERM)
for _signal in _singals:
try:
loop.add_signal_handler(_signal, loop.stop)
except NotImplementedError:
logger.warning(
"Sanic tried to use loop.add_signal_handler "
"but it is not implemented on this platform."
)
if os.name == "nt":
ctrlc_workaround_for_windows(app)
else:
for _signal in [SIGTERM] if run_multiple else [SIGINT, SIGTERM]:
loop.add_signal_handler(_signal, app.stop)
pid = os.getpid()
try:
logger.info("Starting worker [%s]", pid)