Skip to content

Commit 6bf5914

Browse files
minrkvidartf
andauthored
restore preference for SelectorEventLoop on Windows (#513)
* restore preference for SelectorEventLoop on Windows tornado should work better with Selector, even though 6.1 isn't *broken* with proactor. Selector avoids the extra thread, which runs a Selector anyway. * Tests should get the policy set before starting Co-authored-by: Vidar Tonaas Fauske <[email protected]>
1 parent 15417ff commit 6bf5914

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

jupyter_server/pytest_plugin.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@
3131
# "jupyter_core.pytest_plugin"
3232
]
3333

34+
35+
import asyncio
36+
if os.name == "nt" and sys.version_info >= (3, 7):
37+
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
38+
39+
3440
# ============ Move to Jupyter Core =============
3541

3642
def mkdir(tmp_path, *parts):

jupyter_server/serverapp.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,12 +1810,34 @@ def init_httpserver(self):
18101810

18111811
@staticmethod
18121812
def _init_asyncio_patch():
1813-
"""no longer needed with tornado 6.1"""
1814-
warnings.warn(
1815-
"""ServerApp._init_asyncio_patch called, and is longer needed for """
1816-
"""tornado 6.1+, and will be removed in a future release.""",
1817-
DeprecationWarning
1818-
)
1813+
"""set default asyncio policy to be compatible with tornado
1814+
1815+
Tornado 6.0 is not compatible with default asyncio
1816+
ProactorEventLoop, which lacks basic *_reader methods.
1817+
Tornado 6.1 adds a workaround to add these methods in a thread,
1818+
but SelectorEventLoop should still be preferred
1819+
to avoid the extra thread for ~all of our events,
1820+
at least until asyncio adds *_reader methods
1821+
to proactor.
1822+
"""
1823+
if sys.platform.startswith("win") and sys.version_info >= (3, 8):
1824+
import asyncio
1825+
1826+
try:
1827+
from asyncio import (
1828+
WindowsProactorEventLoopPolicy,
1829+
WindowsSelectorEventLoopPolicy,
1830+
)
1831+
except ImportError:
1832+
pass
1833+
# not affected
1834+
else:
1835+
if (
1836+
type(asyncio.get_event_loop_policy())
1837+
is WindowsProactorEventLoopPolicy
1838+
):
1839+
# prefer Selector to Proactor for tornado + pyzmq
1840+
asyncio.set_event_loop_policy(WindowsSelectorEventLoopPolicy())
18191841

18201842
@catch_config_error
18211843
def initialize(self, argv=None, find_extensions=True, new_httpserver=True, starter_extension=None):
@@ -1836,6 +1858,7 @@ def initialize(self, argv=None, find_extensions=True, new_httpserver=True, start
18361858
If given, it references the name of an extension point that started the Server.
18371859
We will try to load configuration from extension point
18381860
"""
1861+
self._init_asyncio_patch()
18391862
# Parse command line, load ServerApp config files,
18401863
# and update ServerApp config.
18411864
super(ServerApp, self).initialize(argv=argv)

0 commit comments

Comments
 (0)