BruceSherwood / vpython-jupyter

This repository has been moved to https://github.com/vpython/vpython-jupyter
64 stars 33 forks source link

Switch to using twisted for websockets in autobahn #91

Closed mwcraig closed 5 years ago

mwcraig commented 5 years ago

This gets most of the way to compatibility with Spyder. Using the asyncio version of autobahn caused a couple of problems with spyder: an event loop was already running, so the starting the websocket server with run_until_complete failed, and running the event loop in a thread seemed to mean that messages never got passed.

I can push a version of that code if anyone wants to take a look -- my experience with asycnio is essentially zero and my understanding is somewhat less than that.

This version works with most of the demo programs. Two that don't work are MousePick.py and Textures.py; in both cases it is mouse picking that is failing.

I don't really understand the code that adds those methods, but as far as I can tell a "pick" event is never generated perhaps because the _waitfor never changes from None in wait.

In an event (no pun intended), we can hopefully get this fixed up Tuesday.

jcoady commented 5 years ago

Hi Matt

You said " my experience with asycnio is essentially zero and my understanding is somewhat less than that." . This video from the 10:45 minute mark to the 15:00 minute mark explains the 7 functions in asyncio that you need to know for the average user.

https://www.youtube.com/watch?v=m28fiN9y_r8&list=PL1LHbPbmRlWG5VcYo0T6Sm93GFdA6TVAI

In the case of picking in vpython it is using blocking I/O so we used the loop.run_in_executor() for this.+

Also have a look at the new asyncio.run() routine which is new in python 3.7. I think spyder defaults now to python 3.7 so it might make sense to look into asyncio.run() which is supposed to simplify things further. If you use asyncio.run() then you no longer need to use the asyncio run_until_complete or run_forever routines. See this video around the 11:00 minute mark.

https://www.youtube.com/watch?v=ReXxO_azV-w

John

From: "Matt Craig" notifications@github.com To: "BruceSherwood/vpython-jupyter" vpython-jupyter@noreply.github.com Cc: "Subscribed" subscribed@noreply.github.com Sent: Monday, November 26, 2018 8:33:24 PM Subject: [BruceSherwood/vpython-jupyter] Switch to using twisted for websockets in autobahn (#91)

This gets most of the way to compatibility with Spyder. Using the asyncio version of autobahn caused a couple of problems with spyder: an event loop was already running, so the starting the websocket server with run_until_complete failed, and running the event loop in a thread seemed to mean that messages never got passed.

I can push a version of that code if anyone wants to take a look -- my experience with asycnio is essentially zero and my understanding is somewhat less than that.

This version works with most of the demo programs. Two that don't work are MousePick.py and Textures.py ; in both cases it is mouse picking that is failing.

I don't really understand the code that adds those methods, but as far as I can tell a "pick" event is never generated perhaps because the _waitfor never changes from None in wait .

In an event (no pun intended), we can hopefully get this fixed up Tuesday. You can view, comment on, or merge this pull request online at:

https://github.com/BruceSherwood/vpython-jupyter/pull/91 Commit Summary

* Switch to using twisted for websockets in autobahn 

File Changes

* M vpython/no_notebook.py (18) 

Patch Links:

* https://github.com/BruceSherwood/vpython-jupyter/pull/91.patch 
* https://github.com/BruceSherwood/vpython-jupyter/pull/91.diff 

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub , or mute the thread .

mwcraig commented 5 years ago

Hi John,

Thanks for the video reference — those were helpful. I’m still confused on a couple of points 9that I’m aware of 😀):

Thanks for your help with this — I really don’t understand well how this part of the code works.

jcoady commented 5 years ago

Hi Matt

I sent an email from an old thread where the picking issue was resolved by calling run_in_executor. Basically when a mousedown event is received then in the handling of this event we send a message to the front end and wait for a response to collect additional information from the front end during the handling of the mousedown event. This sending a message to the front end and waiting for a response is what is blocking. Here is what I wrote in a previous email thread.

"""

Further to my previous email about getting MousePicking demo to work. If you filter in onMessage coroutine for mousedown event then you can just run these one's in the executor and let the other events be processed normally. Changing the onMessage coroutine to the following also works.

async def onMessage(self, data, isBinary): d = json.loads(data.decode("utf-8"))

mock up message format for notebook: evt = msg['content']['data']['arguments'][0]

msg = {'content':{'data':d}} evt = msg['content']['data']['arguments'][0] if evt['event'] in ['mousedown']: loop = asyncio.get_event_loop() await loop.run_in_executor(None, self.widget.handle_msg, msg) else: self.widget.handle_msg(msg)

If you have other code similar to picking where you need to call the front end to get additional information then you can add those events to the list in addition to 'mousedown' event in the line of code from above

if evt['event'] in ['mousedown']:

Any events that need to call the front end to collect additional information need to use the await loop.run_in_executor() routine so that the event loop is freed up to process other messages.

"""

John

From: "Matt Craig" notifications@github.com To: "BruceSherwood/vpython-jupyter" vpython-jupyter@noreply.github.com Cc: "johncoady" johncoady@shaw.ca, "Comment" comment@noreply.github.com Sent: Tuesday, November 27, 2018 8:49:31 PM Subject: Re: [BruceSherwood/vpython-jupyter] Switch to using twisted for websockets in autobahn (#91)

Hi John,

Thanks for the video reference — those were helpful. I’m still confused on a couple of points 9that I’m aware of 😀):

* Why is pick blocking? A better way to phrase that might be what is different about picking as compared to other interactions between the browser and python? I am not suggesting it shouldn’t be blocking, I’m just having trouble understanding what about the current code makes it blocking. 
* I tried playing around a bit with async.run and got an error almost immediately about waiting on a future running in a different thread (I tried to asyncio.run the create_server step, I think). Do you recall why we run the web socket server in a separate thread? 

Thanks for your help with this — I really don’t understand well how this part of the code works.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub , or mute the thread .

mwcraig commented 5 years ago

Closing -- as John immediately recognized, this approach was not going to work