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

Base ipywidgets on Ypy/Yjs #3695

Open
davidbrochart opened this issue Feb 6, 2023 · 6 comments
Open

Base ipywidgets on Ypy/Yjs #3695

davidbrochart opened this issue Feb 6, 2023 · 6 comments

Comments

@davidbrochart
Copy link
Member

Problem

ipywidgets are currently collaborative in the sense that a change to a widget made in a frontend will propagate to every other frontend, but no conflict resolution in the change is done. For instance, we can imagine a widget implementing a text editor and two frontends inserting a different character at the same position simultaneously, that would result in one frontend having "ab" and the other "ba".

Proposed Solution

We should use CRDTs for synchronizing widgets, as we do in JupyterLab document collaboration.
I have started ypywidgets and added support for it in jpterm.

ypywidgets.mp4
@bollwyvl
Copy link
Contributor

bollwyvl commented Feb 8, 2023

While I'm bullish on CRDTs at the interface, I'm lukewarm on adopting y-based stuff as the one true widgets implementation, as it adds a fairly non-trivial dependency and build chain.

Getting the above demo running in a jupyterlite/pyodide-based site would go a long way towards alleviating that specific concern.

Getting past "can i install it", such a change (which would certainly be a major release), then there would be the issues of:

@davidbrochart
Copy link
Member Author

I would argue that the dependency/build chain issue will have to be solved anyway, otherwise JupyterLite will be stuck with JupyterLab<4.0 forever.

@bollwyvl
Copy link
Contributor

bollwyvl commented Feb 8, 2023

JupyterLite will be stuck with JupyterLab<4.0

Will be stuck without RTC. Widgets will work well before then.

@maartenbreddels
Copy link
Member

I am not sure about this change, but at the same time, quite interested in it!

I am not sure ipywidgets is the layer where this problem should be tackled. I think this should be the responsibility of the application layer (like the state management layer). I am not convinced having true collaborative widgets is a common use case. Having multiple frontends supported is great (such that changing a slider in 1 frontend will echo to the other), and we already have that working now in ipywidgets 8.
But I do not think the situations where multiple people are in the same kernel playing with the same widget is a very common use case.

Happy to discuss this further, and happy to change my mind, but reluctant to change the relatively simple model we have now.

@davidbrochart
Copy link
Member Author

I think CRDTs do a better job at delta-updates than we do. For instance if one element of a list has changed, then only that value change is emitted, instead of the whole list as in our current implementation.
I also think that we will soon face the situation where the kernel is just another client modifying a shared document. For instance, we can imagine a JupyterLab (collaborative) notebook, and a kernel linting it as you type. Or a kernel programmatically modifying a JupyterCAD widget that could also be opened as a shared document (without a kernel) in a browser on another machine (@trungleduc is experimenting with this).
The advantages of making JupyterLab shared documents and Jupyter widgets use the same infrastructure become obvious in that case.

@bollwyvl
Copy link
Contributor

bollwyvl commented Feb 9, 2023

These are interesting cases, to be sure.

But before invalidating the entire existing widget ecosystem, this could be demonstrated by integrating along with those existing things. A ypy-traittypes package, similar to traittypes that gave folk the ability to use y-backed stuff for their specific cases would indeed be helpful.

class CadThinger(Widget):
    cad_file: whatever = YpyFileTrait(schema=however_you_get_this).tag(sync=true, **y_serialization)

CadThinger(cad_file=however_you_get_this)

If this cracks open another comm_id with its own comm_target, that doesn't mess with the existing one, can be serialized to a notebook's metadata, etc. then everything is great. If you can't install that package, you can't use widgets that use those traits.

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

No branches or pull requests

3 participants