New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tornado 5.0 compatibility #7308
Comments
Is there a description of the changes somewhere? |
Well the majority of failures (though not all I don't think) seem to be this:
So let's start there. @bdarnell do you have any comments or guidance? Are there any migration notes available? |
Well, it looks like this change to
I'm not sure what the appropriate change to make is, though. |
I think that whenever you explicitly provide an |
Unfortunately it doesn't seem to be as simple as that. Doing that causes several tests to hang completely. |
FWIW
As for the tests we do manage io_loops explicitly in a way I only vaguely understand. Is there an expected timeframe for 5.0? I think in the short term may only be able to update the dependencies to |
There's no strict timeline for Tornado 5.0 yet; I want to work with projects like bokeh to make sure the new version will work for you before it's released. As @mrocklin says, the The |
@bdarnell First, please let me say thank you for your help with this. First here is a diff I'm starting with
Then if I run:
I see these two failures
But those tests hang completely. This is only if I hit ctrl-c to stop them. Then |
As for explicit management I think this is about it: https://github.com/bokeh/bokeh/blob/master/bokeh/server/tests/utils.py#L59 |
Jus as a heads up,
|
Reported in: jupyter/notebook#3023
Fixed in: jupyter/notebook#3034
|
OK, when I said all the tests were passing, I had fat-fingered my PYTHONPATH tweaks to run against tornado master, so it was still using 4.5. Now I'm able to reproduce the behavior from #7308 (comment) Here's a diff that gets all of those tests passing but one: diff --git a/bokeh/server/server.py b/bokeh/server/server.py
index ba5243730..2e80103df 100644
--- a/bokeh/server/server.py
+++ b/bokeh/server/server.py
@@ -393,10 +393,7 @@ class Server(BaseServer):
try:
tornado_app = BokehTornado(applications, extra_websocket_origins=extra_websocket_origins, prefix=self.prefix, **kwargs)
- if io_loop is not None:
- http_server = HTTPServer(tornado_app, io_loop=io_loop, **http_server_kwargs)
- else:
- http_server = HTTPServer(tornado_app, **http_server_kwargs)
+ http_server = HTTPServer(tornado_app, **http_server_kwargs)
http_server.start(opts.num_procs)
http_server.add_sockets(sockets)
diff --git a/bokeh/server/tests/test_callbacks.py b/bokeh/server/tests/test_callbacks.py
index c08bf752f..05f07f645 100644
--- a/bokeh/server/tests/test_callbacks.py
+++ b/bokeh/server/tests/test_callbacks.py
@@ -31,6 +31,12 @@ def run(loop):
class LoopAndGroup(object):
def __init__(self, quit_after=None):
self.io_loop = IOLoop()
+ try:
+ import asyncio
+ except ImportError:
+ pass
+ else:
+ asyncio.set_event_loop(self.io_loop.asyncio_loop)
self.group = _CallbackGroup(self.io_loop)
if quit_after is not None:
diff --git a/bokeh/server/tests/test_server.py b/bokeh/server/tests/test_server.py
index ac930aeaa..15b6a9d20 100644
--- a/bokeh/server/tests/test_server.py
+++ b/bokeh/server/tests/test_server.py
@@ -143,8 +143,7 @@ def test__lifecycle_hooks():
def check_done():
if len(handler.hooks) == 4:
server.io_loop.stop()
- server_load_checker = PeriodicCallback(check_done, 1,
- io_loop=server.io_loop)
+ server_load_checker = PeriodicCallback(check_done, 1)
server_load_checker.start()
server.io_loop.start()
server_load_checker.stop()
diff --git a/bokeh/server/tests/utils.py b/bokeh/server/tests/utils.py
index b43c2e540..417f306d5 100644
--- a/bokeh/server/tests/utils.py
+++ b/bokeh/server/tests/utils.py
@@ -41,7 +41,7 @@ def websocket_open(io_loop, url, origin=None):
request = HTTPRequest(url)
if origin is not None:
request.headers['Origin'] = origin
- websocket_connect(request, callback=handle_connection, io_loop=io_loop)
+ websocket_connect(request, callback=handle_connection)
io_loop.start()
@@ -60,6 +60,12 @@ class ManagedServerLoop(object):
def __init__(self, application, **server_kwargs):
loop = IOLoop()
loop.make_current()
+ try:
+ import asyncio
+ except ImportError:
+ pass
+ else:
+ asyncio.set_event_loop(loop.asyncio_loop)
server_kwargs['io_loop'] = loop
self._server = Server(application, **server_kwargs)
def __exit__(self, type, value, traceback):
diff --git a/bokeh/server/tornado.py b/bokeh/server/tornado.py
index 153e64644..10903b9b7 100644
--- a/bokeh/server/tornado.py
+++ b/bokeh/server/tornado.py
@@ -232,15 +232,13 @@ class BokehTornado(TornadoApplication):
self._clients = set()
self._stats_job = PeriodicCallback(self._log_stats,
- self._stats_log_frequency_milliseconds,
- io_loop=self._loop)
+ self._stats_log_frequency_milliseconds)
self._cleanup_job = PeriodicCallback(self._cleanup_sessions,
- self._check_unused_sessions_milliseconds,
- io_loop=self._loop)
+ self._check_unused_sessions_milliseconds)
if self._keep_alive_milliseconds > 0:
- self._ping_job = PeriodicCallback(self._keep_alive, self._keep_alive_milliseconds, io_loop=self._loop)
+ self._ping_job = PeriodicCallback(self._keep_alive, self._keep_alive_milliseconds)
else:
self._ping_job = None I'm going to change Note that I had to reintroduce the bokeh/bokeh/client/connection.py Lines 73 to 76 in 90c3f6c
The remaining failure is
This is a known consequence of the move to asyncio: the timing of callbacks in some situations has changed. If this is significant for you I can look into this further, but otherwise I would suggest relaxing this test. |
@bdarnell thanks, I have made a PR with your initial diff to help focus work and iteration. A few observations on my machine:
|
Correct. That whole block goes away.
I haven't dug into this yet but I believe I'll be able to make it work the way it did before (at least as long as there's not a deeper issue lurking behind the multiprocess issue) I think the |
@bdarnell great I pulled the new changes and updated the PR to remove the explicit asyncio blocks. I believe all tests are passing now on both 4.x and 5.0dev. The
(there may be other messages in other examples) So perhaps just some usage on our end to tighten up. |
The |
@bdarnell great, I look forward to testing it out. On another issue, do you expect to make 5.0 pre-releases available any time? At some point we will need to add a build stage to test with Tornado 5.0 |
Yes, I've just uploaded an alpha to pypi: https://pypi.python.org/pypi/tornado/5.0a1 |
@bdarnell fantastic, I will start to figure out how to include it in our CI tests. |
And there's now a beta, 5.0b1. I've been filing this issue on a number of other projects; since you already have one open I'm including the message here. Tornado 5.0 is currently in beta, and I'm filing issues with prominent Full release notes are If you've already tested with Tornado 5.0b1 (or temporarily pinned |
Dask tests show the following bokeh/tornado issues Traceback (most recent call last):
File "/home/mrocklin/workspace/tornado/tornado/gen.py", line 831, in callback
result_list.append(f.result())
File "/home/mrocklin/workspace/tornado/tornado/gen.py", line 301, in wrapper
yielded = next(result)
File "/home/mrocklin/workspace/distributed/distributed/worker.py", line 352, in _start
self.start_services(listen_host)
File "/home/mrocklin/workspace/distributed/distributed/worker.py", line 313, in start_services
self.services[k].listen((listen_ip, port))
File "/home/mrocklin/workspace/distributed/distributed/bokeh/core.py", line 29, in listen
**self.server_kwargs)
File "/home/mrocklin/Software/anaconda/lib/python3.6/site-packages/bokeh/server/server.py", line 397, in __init__
http_server = HTTPServer(tornado_app, io_loop=io_loop, **http_server_kwargs)
File "/home/mrocklin/workspace/tornado/tornado/util.py", line 312, in __new__
instance.initialize(*args, **init_kwargs)
TypeError: initialize() got an unexpected keyword argument 'io_loop' Also ../../Software/anaconda/lib/python3.6/site-packages/bokeh/server/server.py:413: in __init__
super(Server, self).__init__(io_loop, tornado_app, http_server)
../../Software/anaconda/lib/python3.6/site-packages/bokeh/server/server.py:125: in __init__
self._tornado.initialize(io_loop)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <bokeh.server.tornado.BokehTornado object at 0x7f6d6ba5c390>
io_loop = <tornado.platform.asyncio.AsyncIOLoop object at 0x7f6d6bd14fd0>
def initialize(self, io_loop):
''' Start a Bokeh Server Tornado Application on a given Tornado IOLoop.
'''
self._loop = io_loop
for app_context in self._applications.values():
app_context._loop = self._loop
self._clients = set()
self._stats_job = PeriodicCallback(self._log_stats,
self._stats_log_frequency_milliseconds,
> io_loop=self._loop)
E TypeError: __init__() got an unexpected keyword argument 'io_loop' VersionsIn [1]: import bokeh, tornado
In [2]: tornado.version
Out[2]: '5.0b1'
In [3]: bokeh.__version__
Out[3]: '0.12.14dev6' |
@mrocklin this PR has not been merged yer |
Ah! I missed the reference to the PR. I'll test against that. Thanks @bryevdv |
TypeError: websocket_connect() got an unexpected keyword argument 'io_loop' Links: kbase/narrative#1266 bokeh/bokeh#7308
Note that the next verion of Tornado, 5.0, will include breaking changes which break the existing Bokeh test suite.
The text was updated successfully, but these errors were encountered: