Add fall back for Windows even loop fetching (#2421)

This commit is contained in:
Adam Hopkins 2022-04-17 05:25:41 -04:00 committed by GitHub
parent 00218aa9f2
commit cc97287f8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 16 additions and 8 deletions

View File

@ -1 +1 @@
__version__ = "22.3.0"
__version__ = "22.3.1"

View File

@ -252,7 +252,13 @@ class Sanic(BaseSanic, RunnerMixin, metaclass=TouchUpMeta):
"Loop can only be retrieved after the app has started "
"running. Not supported with `create_server` function"
)
return get_running_loop()
try:
return get_running_loop()
except RuntimeError:
if sys.version_info > (3, 10):
return asyncio.get_event_loop_policy().get_event_loop()
else:
return asyncio.get_event_loop()
# -------------------------------------------------------------------- #
# Registration

View File

@ -72,7 +72,7 @@ def ctrlc_workaround_for_windows(app):
"""Asyncio wakeups to allow receiving SIGINT in Python"""
while not die:
# If someone else stopped the app, just exit
if app.is_stopping:
if app.state.is_stopping:
return
# Windows Python blocks signal handlers while the event loop is
# waiting for I/O. Frequent wakeups keep interrupts flowing.

View File

@ -3,6 +3,7 @@ import os
import signal
from queue import Queue
from types import SimpleNamespace
from unittest.mock import MagicMock
import pytest
@ -74,11 +75,12 @@ def test_windows_workaround():
# Windows...
class MockApp:
def __init__(self):
self.is_stopping = False
self.state = SimpleNamespace()
self.state.is_stopping = False
def stop(self):
assert not self.is_stopping
self.is_stopping = True
assert not self.state.is_stopping
self.state.is_stopping = True
def add_task(self, func):
loop = asyncio.get_event_loop()
@ -91,11 +93,11 @@ def test_windows_workaround():
if stop_first:
app.stop()
await asyncio.sleep(0.2)
assert app.is_stopping == stop_first
assert app.state.is_stopping == stop_first
# First Ctrl+C: should call app.stop() within 0.1 seconds
os.kill(os.getpid(), signal.SIGINT)
await asyncio.sleep(0.2)
assert app.is_stopping
assert app.state.is_stopping
assert app.stay_active_task.result() is None
# Second Ctrl+C should raise
with pytest.raises(KeyboardInterrupt):