Skip to content

Commit

Permalink
restore preference for SelectorEventLoop on Windows (#513)
Browse files Browse the repository at this point in the history
* 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]>
  • Loading branch information
minrk and vidartf authored May 13, 2021
1 parent 15417ff commit 6bf5914
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 6 deletions.
6 changes: 6 additions & 0 deletions jupyter_server/pytest_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@
# "jupyter_core.pytest_plugin"
]


import asyncio
if os.name == "nt" and sys.version_info >= (3, 7):
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())


# ============ Move to Jupyter Core =============

def mkdir(tmp_path, *parts):
Expand Down
35 changes: 29 additions & 6 deletions jupyter_server/serverapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -1810,12 +1810,34 @@ def init_httpserver(self):

@staticmethod
def _init_asyncio_patch():
"""no longer needed with tornado 6.1"""
warnings.warn(
"""ServerApp._init_asyncio_patch called, and is longer needed for """
"""tornado 6.1+, and will be removed in a future release.""",
DeprecationWarning
)
"""set default asyncio policy to be compatible with tornado
Tornado 6.0 is not compatible with default asyncio
ProactorEventLoop, which lacks basic *_reader methods.
Tornado 6.1 adds a workaround to add these methods in a thread,
but SelectorEventLoop should still be preferred
to avoid the extra thread for ~all of our events,
at least until asyncio adds *_reader methods
to proactor.
"""
if sys.platform.startswith("win") and sys.version_info >= (3, 8):
import asyncio

try:
from asyncio import (
WindowsProactorEventLoopPolicy,
WindowsSelectorEventLoopPolicy,
)
except ImportError:
pass
# not affected
else:
if (
type(asyncio.get_event_loop_policy())
is WindowsProactorEventLoopPolicy
):
# prefer Selector to Proactor for tornado + pyzmq
asyncio.set_event_loop_policy(WindowsSelectorEventLoopPolicy())

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

0 comments on commit 6bf5914

Please sign in to comment.