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
Snapshot widget state when syncing #1044
Comments
Can you open up the debugger and see if the widget sync message is getting sent over the websocket? I can help you find where this message should be - let me know if you want help finding it. |
So now go to the 'network' tab in the debug window, and filter to just find websocket (WS) connections. Take a look at the messages going back and forth on the websocket channel. |
I tried to reproduce, but ran into errors importing pytraj. Do you have a minimal example not using pytraj? |
either
|
(it may be more helpful to try to debug this on chat, as we can communicate more quickly than here. Please ping me or @SylvainCorlay if you're around on https://gitter.im/ipython/ipywidgets) |
preliminary results: it appears that the widget is sending a number of custom messages, which increments the pending_msgs, but it never gets decremented back to 0, so any .touch() after that queues up its sync message instead of sending. |
@hainm, does changing this line to Basically, the problem ended up being that the frontend sent a message to the backend without setting a callback. The callback is how we keep track of the number of messages in flight. Since the callback wasn't set, the message counter wasn't ever decremented to 0, and that blocked all other outgoing messages. The view send function automatically sets the callbacks, whereas the model send function relies on you setting the appropriate callbacks (such as in https://github.com/ipython/ipywidgets/blob/master/jupyter-js-widgets/src/widget.ts#L694). Next thing to look at - why doesn't the model.send function set a callback, since the model send function is the one incrementing the pending messages counter. That seems to be a bit of spaghetti code on our end right now. |
hi, I think the
|
Can you try it? I'm betting you'll be surprised :) |
it does not fix that. I got new issue if following your change ( Exception in status msg handler TypeError: Converting circular structure to JSON
at JSON.stringify (<anonymous>)
at Object.serialize (main.min.js:22370)
at Kernel.send_shell_message (main.min.js:23028)
at Comm.send (main.min.js:22203)
at DOMWidgetModel.WidgetModel._handle_status (:8869/nbextensions/jupyter-js-widgets/extension.js?v=20170131204412:16669) |
oh right, we had that issue too. Hmm...interesting, it's coming from _handle_status? Let me do some more digging tomorrow. I really think the underlying issue with the sync not getting sent is that one message send that doesn't have callbacks. But let me look at this and see if I can see what the issue is with this. |
Oh, right, it's coming from handle_status because that's where the sync message is actually being sent (and the serialization is actually being done). It's a good thing that we're getting the circular structure error - that's telling us that at least now it's trying to sync to the backend. There's something wrong with the data it's trying to send to the backend, though. |
Here is a function that can detect circular references:
I modified the NGLViewClass to have this function:
That should catch when a model has circular references at the time the model is saved. However, no circular references show up at the time when touch() is called. However, if I put a similar block of code in ipywidgets right when the message in the model's message buffer is actually sent, I do detect circular references, such as these two paths in the object tree pointing to the same object: Does this make sense? Does this seem right to you? I can think of two things we can do:
|
I tag @arose here with the hope that he can reply to you. I am quite naive with JS :D. |
It looks like the problem is trying to sync the |
@arose: picked in only one example. even |
@hainm - the problem is that the sync message is delayed until the in-flight comm messages are resolved. When the comm messages finish being processed, it tries to send all of the sync data that's been building up from multiple We need to do some changes on our end, namely serialize the data right when |
also raising a circular references error? |
There's a lot more going on behind the scenes than just that one data value. As best as I can guess, it says that it needs to sync some large amount of state, which doesn't contain circular references, and then the state changes to have some circular references before it actually serializes the state to JSON. |
It sounds like on the nglView widget's end, we need to be smarter about the data we're actually syncing, like @arose mentions above? I'll work on the ipywidgets end - making it so that the syncing takes a snapshot of the state when you ask it to sync, and getting the state updates merging to work. It sounds like there will be more work needed to make sure that we are only syncing state that we want to sync on the ngl widget side. |
Thanks. I will take care of nglview. This would help closing this too #1038 |
This is going to be a major code refactoring and change, I think better saved for after 6.0. |
https://github.com/arose/nglview/blob/master/nglview/widget.py#L87 - but with |
thanks @jasongrout. After updating nglview code, there is another similar error but I don't know how to fix. TraitError: The '_model_module' trait of a TrajectoryPlayer instance must be a unicode string, but a value of None <class 'NoneType'> was specified. TrajectoryPlayer inherits from https://github.com/arose/nglview/blob/master/nglview/player.py#L22 |
It's the same fix, but for that widget.
…On Wed, Apr 12, 2017, 20:04 Hai Nguyen ***@***.***> wrote:
thanks @jasongrout <https://github.com/jasongrout>. After updating
nglview code, there is another similar error but I don't know how to fix.
TraitError: The '_model_module' trait of a TrajectoryPlayer instance must be a unicode string, but a value of None <class 'NoneType'> was specified.
TrajectoryPlayer inherits from ipywidgets.widgets.domwidget.DOMWidget
https://github.com/arose/nglview/blob/master/nglview/player.py#L22
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1044 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AALwZjcbam17EDTtj3_dfoHHoLNueb6Rks5rvWZ9gaJpZM4LlO5G>
.
|
Hi
But there is no js code for that widget. Its class only inherits from DOMWidget.
What should I do now? And why this is different from 5.2.2?
Hai
… On Apr 12, 2017, at 8:33 PM, Jason Grout ***@***.***> wrote:
It's the same fix, but for that widget.
On Wed, Apr 12, 2017, 20:04 Hai Nguyen ***@***.***> wrote:
> thanks @jasongrout <https://github.com/jasongrout>. After updating
> nglview code, there is another similar error but I don't know how to fix.
>
> TraitError: The '_model_module' trait of a TrajectoryPlayer instance must be a unicode string, but a value of None <class 'NoneType'> was specified.
>
> TrajectoryPlayer inherits from ipywidgets.widgets.domwidget.DOMWidget
>
> https://github.com/arose/nglview/blob/master/nglview/player.py#L22
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <#1044 (comment)>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AALwZjcbam17EDTtj3_dfoHHoLNueb6Rks5rvWZ9gaJpZM4LlO5G>
> .
>
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
|
Oh, very interesting! My thought in making that change is that there should always be a javascript subclass. Can you describe a bit more about how TrajectoryPlayer works? I see it is syncing a lot of attributes - how are those used in the browser? |
hi, There is nothing special about this class. If we ignore |
If change TrajectoryPlayer(DOMWidget) to TrajectoryPlayer(object), there will be error ---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-3-a2707b8cc497> in <module>()
1 from nglview.player import TrajectoryPlayer
2
----> 3 TrajectoryPlayer(object())
nglview/nglview/player.py in __init__(self, view, step, delay, sync_frame, min_delay)
67 min_delay=40):
68 self._view = view
---> 69 self.step = step
70 self.sync_frame = sync_frame
71 self.delay = delay
miniconda3/envs/jupyterlab/lib/python3.5/site-packages/traitlets/traitlets.py in __set__(self, obj, value)
581 raise TraitError('The "%s" trait is read-only.' % self.name)
582 else:
--> 583 self.set(obj, value)
584
585 def _validate(self, obj, value):
miniconda3/envs/jupyterlab/lib/python3.5/site-packages/traitlets/traitlets.py in set(self, obj, value)
555
556 def set(self, obj, value):
--> 557 new_value = self._validate(obj, value)
558 try:
559 old_value = obj._trait_values[self.name]
miniconda3/envs/jupyterlab/lib/python3.5/site-packages/traitlets/traitlets.py in _validate(self, obj, value)
588 if hasattr(self, 'validate'):
589 value = self.validate(obj, value)
--> 590 if obj._cross_validation_lock is False:
591 value = self._cross_validate(obj, value)
592 return value
AttributeError: 'TrajectoryPlayer' object has no attribute '_cross_validation_lock' |
Ah. You should inherit from HasTraits: from traitlets import HasTraits
class TrajectoryPlayer(HasTraits): That gives you the observe decorator. There's also no need for the |
cools. just tried and ok. |
Per (Not sure what' the difference between class NGLWidget(DOMWidget):
_view_name = Unicode("NGLView").tag(sync=True)
_view_module = Unicode("nglview-js-widgets").tag(sync=True)
_model_name = Unicode("NGLView").tag(sync=True)
_model_module = Unicode("nglview-js-widgets").tag(sync=True) Got new kind of error: Could not create model:
Model name NGLView
Model module nglview-js-widgets
Model module version *
ModelType._deserialize_state is not a function |
Okay, for now, how about you change it to: class NGLWidget(DOMWidget):
_view_name = Unicode("NGLView").tag(sync=True)
_view_module = Unicode("nglview-js-widgets").tag(sync=True)
_model_name = Unicode("DOMWidgetModel").tag(sync=True)
_model_module = Unicode("jupyter-js-widgets").tag(sync=True) |
wow, that actually work. And I confirm that the original issue is solved too. thanks very much. cheers. |
Hi @jasongrout The issue appears again. May be adding regression test for this? |
Sorry, this issue was a while ago. What issue appeared again? |
sorry, I should be clear. This issue appears again: #1044 (comment) In short: |
What errors are you seeing? |
From above:
This should be done now.
Did you look at this, to make sure you aren't trying to sync a circular reference? Last I remember, this ngl view still had an issue: #1044 (comment) |
Yeah, |
I just checkout the commit in #1270 and try again and the |
strangely there is no error in console. |
Can you try checking the "Pause on exceptions" and running the code, to try to see where the error is? |
Let's continue conversation on #1375 to track whatever is happening this time. |
Summary
We should snapshot the widget state when syncing state from the frontend to the kernel, since the sync may happen asynchronously because of the throttling.
Original issue
hi
we have simple code in
nglview
that works fine withipywidgets 5.2.2
.However, there is no effect if using
mode.set(...)
in6.0.0.beta5
version.one example:
will not update
camera_str
in Python.https://github.com/arose/nglview/blob/master/js/src/widget_ngl.js#L77-L82
The text was updated successfully, but these errors were encountered: