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

Widget out of sync: fundamental issue? #3111

Closed
maartenbreddels opened this issue Feb 11, 2021 · 1 comment · Fixed by #3195
Closed

Widget out of sync: fundamental issue? #3111

maartenbreddels opened this issue Feb 11, 2021 · 1 comment · Fixed by #3195

Comments

@maartenbreddels
Copy link
Member

Code

import ipywidgets as widgets
import time

text = widgets.Text(value="...", continuous_update=False)
def on_change(change):
    if text.value == "sleep":
        time.sleep(6)
        text.value = "I computed for 6 seconds"
text.observe(on_change, "value")
text

Demo

sync-bug

What happens?

If we enter 'sleep', an update event is send to the kernel, which takes 6 seconds to finish. Before it finishes, we change the text to "bug?", which is queued at the kernel, because the time.sleep(6) is still ongoing. Next, we send an update event from the kernel to the frontend, changing the Text value to "I computed for 6 seconds", after which we process the queued message from the frontend which changes the kernel side value to "bug?".

Now the frontend thinks the value is "I computed for 6 seconds" while the kernel thinks it is "bug?"

What I think should happen

There must be a ton of literature written about keeping two systems in sync, but I think there should be an agreement of which side holds the ultimate source of truth. Since ipywidgets is mainly about programming from the kernel, I think that should be the kernel by default, and therefore I think the kernel should by default echo back the value to the frontend.

In this case, the "bug?" update message should be sent back to the frontend. The reason we don't do that, is that we implicitly assume the message (update to "bug?") was generated AFTER the change to "I computed for 6 seconds" and therefore we assume that the frontend also has that value.

There are situations, like in ipywebrtc where the 'source of truth' is the frontend, since it generates the data (video stream), so there should be an opt-out way of echoing back changes.

Context

This bug/feature was discovered by @mariobuikhuizen while trying to solve an infinite echo problem: spacetelescope/jdaviz#185 🤷

maartenbreddels added a commit to maartenbreddels/ipywidgets that referenced this issue May 4, 2021
As described in jupyter-widgets#3111 it can happen that a frontend can get out of sync
due to not echoing back messages from the frontend.

Widgets can opt out of this behaviour if it is too costly and/or does
not make sense, e.g. the data from the file widget.

Fixes jupyter-widgets#3111
@ellisonbg
Copy link
Member

I think this directly relates to the ongoing work on JupyterLab to add a shared data model (often known as real-time collaboration) to JupyterLab (jupyterlab/jupyterlab#10118). We are starting to use Yjs as a data model for notebooks and text files and it handles the synchronization of distributed state. Eventually, to make jupyter widgets work in a real-time collaboration context, we will have to dive into that - a side effect would be to address this issue as well.

maartenbreddels added a commit to maartenbreddels/ipywidgets that referenced this issue Dec 7, 2021
As described in jupyter-widgets#3111 it can happen that a frontend can get out of sync
due to not echoing back messages from the frontend.

Widgets can opt out of this behaviour if it is too costly and/or does
not make sense, e.g. the data from the file widget.

Fixes jupyter-widgets#3111
@vidartf vidartf mentioned this issue Feb 28, 2022
6 tasks
jasongrout pushed a commit to jasongrout/ipywidgets that referenced this issue Mar 2, 2022
As described in jupyter-widgets#3111 it can happen that a frontend can get out of sync
due to not echoing back messages from the frontend.

Widgets can opt out of this behaviour if it is too costly and/or does
not make sense, e.g. the data from the file widget.

Fixes jupyter-widgets#3111

avoid echo/jitter in frontend

put jupyter echo behaviour behind a flag

minimize diff

remove spacing

prettier

lint

fix: handle messages correctly when echoing disabled

minimize diff

minimize diff

fix and test

fix test, do not use set (no determinstic order)

fix: echos from other clients are not unexpected

comment and reformat

better variable name

Work-in-progress update for echo updates to have their own key in update messages

Update protocol description

Update js echo logic to handle echo_state key

Starts fixing jupyter-widgets#3392

WIP consolidating logic for property lock.

WIP simple reflection immediately on setting state.

WIP Remove code about sending echo messages combined with any kernel updates

Remove comments and simplify so the final diff is simpler

Add debug test runner

Experiment making echo updates a separate message

Bump widget protocol version number back to 2.1.0

Update no_echo metadata name to echo_update for clarity.

Having a negative in the name was confusing to me, so I renamed the property echo_update. Set it to False to disable echos for that attribute.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants