Skip to content
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

Add tornado #25

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Add tornado #25

wants to merge 1 commit into from

Conversation

bollwyvl
Copy link

@bollwyvl bollwyvl commented Jan 6, 2019

Thanks for all the work!

This adds a tornado handler and context, which is a very minimal change on top of websockets_lib.py. Tornado is a tad more verbose, I guess, but pretty useful and important in its own right. While theoretically possible, I haven't bothered with python2 support.

Because tornado's websocket on_message implementation is callback-based, I've used an asyncio.Queue to make it act more like what other things would expect, but it seems like handle might need some more information. I've left it looking for the magic recv, just to keep the line changes down.

I couldn't immediately identify any places to plug in new tests... guess I'll see what CI does!

@kinow
Copy link

kinow commented Jul 16, 2019

Travis build on Python 2 is failing due to pathlib, which is part of standard lib in Python 3. Should we add pathlib as requirement, or maybe go with os, path, etc to keep backward compatibility?

@bollwyvl
Copy link
Author

bollwyvl commented Jul 16, 2019 via email

@@ -0,0 +1,47 @@
from asyncio import Queue
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the bigger problem than pathlib for py2 support and would need figuring out...

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't worry about py2 support. We'll just call this a py3-only supported backend :)

@@ -0,0 +1,114 @@
from inspect import isawaitable

from asyncio import ensure_future, wait, shield
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And all this...

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Tornado also offers something similar to ensure_future (not sure about wait and shield tho)

@bollwyvl
Copy link
Author

Yeah, don't know how much I want to wade back into @gen.coroutines over async...

@kinow
Copy link

kinow commented Jul 17, 2019

Yeah, don't know how much I want to wade back into @gen.coroutines over async...

Yeah.. it would be way easier to update/maintain this if Py3+ only was possible.

@bollwyvl
Copy link
Author

Yeah.. it would be way easier to update/maintain this if Py3+ only was possible.

Is there stated official cut-off release for Py2? I could certainly hold my breath until one was announced, as I have already vendored it into deathbeds/jupyter-graphql#2, which hasn't been moving much.

@kinow
Copy link

kinow commented Jul 26, 2019

Had another look at the changes today, and was thinking in sending a PR to @bollwyvl 's branch to support Py2 as we also want this feature.

However, graphql_ws.aiohttp is Py3 only. So it looks to me like a few files like base and constants are Py2 compatible. And gevent I think.

But if the user wants to use websockets or asyncio, then that part of the library is Py3 only? The tests pass on Py2, and I can also install the library with Py2. Running the examples with websockets_lib or asyncio/aiohttp result in error in Py2.

So if that's correct, I think we can ignore the Py2 requirement, and use @bollwyvl 's code as-is? The master branch is not passing in Travis as well - https://travis-ci.org/graphql-python/graphql-ws/builds/432902410

@bollwyvl
Copy link
Author

to support Py2 as we also want this feature.

That's great: no doubt tornado can support py2, and it would not be a big deal to support it, and could likely be written and tested in such a way as to support both tornado 5 and 6, but I am disinclined to advertise support for py2 at this time.

The master branch is not passing in Travis as well

Yeah, that makes it hard to get started as a contributor.

part of the library is Py3 only

Yeah, I think a pinned issue/README statement of graphql-ws Python 2 support would be reasonable to add, including how long python 2 support would continue.

@dwsutherland
Copy link

Ping @syrusakbary

(might be busy with wasmerio I suppose..)

@dwsutherland
Copy link

@jkimbo - I know you haven't been involved with this one.. But no maintainers appear active here...

Do you know what's happening with this project? it seems to be stagnant..
Is it anything to do with this graphql-core-next?
https://github.com/graphql-python/graphql-ws/tree/next/master

It would be good to have this PR in ...

class SubscriptionHandler(websocket.WebSocketHandler):
def initialize(self, sub_server):
self.subscription_server = subscription_server
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am trying the example locally, but this part was a bit confusing. We have the subscription_server defined before this class declaration.

Here we get self.subscription_server = subscription_server , but we also get a sub_server parameter?

The open() method uses not self.subscription_server , but the previously created subscription_server .

@kinow
Copy link

kinow commented Sep 5, 2019

Tested the pull request with a small Vue.js application and it worked (thanks @dwsutherland for the help troubleshooting a few minor issues).

https://github.com/kinow/tornado-sandbox/tree/master/web5 (copied the tornado.py from this project as tornado_ws_wip.py there)

@kinow kinow mentioned this pull request Dec 28, 2019
3 tasks
@kinow
Copy link

kinow commented May 20, 2020

Ping. We've been happily using the code in this pull request in https://github.com/cylc/cylc-uiserver. Any plans on review/merging it? Thanks!

@SmileyChris
Copy link
Contributor

Hi @kinow -- I'm new to the team and trying to actively get through the PRs and assess them. I'm currently doing a reshuffle of the core code to split out the common sync and async code across the current servers. Hopefully it should make a smaller effort to integrate, but it may require some rewriting.

@kinow
Copy link

kinow commented May 20, 2020

Hi @SmileyChris !

Thanks for the quick reply!

Hi @kinow -- I'm new to the team and trying to actively get through the PRs and assess them. I'm currently doing a reshuffle of the core code to split out the common sync and async code across the current servers.

Sounds great! graphql-ws has been really useful already, so I think it will be even better after these changes.

Hopefully it should make a smaller effort to integrate, but it may require some rewriting.

@bollwyvl 's code is simple well structured, and we have become somewhat familiar with it. So we'd be happy to help testing it with our current system or even trying to suggest how to fix some conflicts if necessary.

Thanks!

Copy link

@kinow kinow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a few comments about changes/issues we had after using this code. No blockers, just notes about what we changed 👍 Keeping my +1 for this PR :-)

await self.queue.put(message)

async def recv(self):
return await self.queue.get()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the project where we have been using this code for a while, we ran into issues with the blocking queue here, where some subscriptions would hang, causing memory leaks.

We added a recv_nowait. This way the code calling the queue had a chance to look if the connection was interrupted, and then clear up the remaining asyncio tasks used for the subscription.

<script src="//cdn.jsdelivr.net/react/15.0.0/react-dom.min.js"></script>
<script src="//cdn.jsdelivr.net/graphiql/${GRAPHIQL_VERSION}/graphiql.min.js"></script>
<script src="//unpkg.com/subscriptions-transport-ws@${SUBSCRIPTIONS_TRANSPORT_VERSION}/browser/client.js"></script>
<script src="//unpkg.com/[email protected]/browser/client.js"></script>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We updated our template recently, using the latest version of graphiql.js, and had issues with the graphiql-subscriptions-fetcher.

Unfortunately the repo for this dependency is archived and hasn't been updated in a while, which causes subscriptions to fail when you update it. So for this PR I think we should leave the current versions, even if old.

Ref: https://github.com/cylc/cylc-ui/pull/457/files#diff-1696770be90f4f901322de74987fdf90R23

@SmileyChris
Copy link
Contributor

#46 is the PR tracking the base class rewrites. You may want to check out that branch to get an idea about building on top of that

@oliver-sanders
Copy link

We have been using code derived from this for a while, it works well, thanks all.

Happy to review differences and contribute any positive changes once this is in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants