microsoft / FluidFramework

Library for building distributed, real-time collaborative web applications
https://fluidframework.com
MIT License
4.73k stars 532 forks source link

Python Implementation of the Fluid Server? #4449

Closed echarles closed 3 years ago

echarles commented 3 years ago

Hi, I am working on the Jupyter Realtime Collaboration project (https://github.com/jupyterlab/rtc) and one of the requirement is to avoid Node.js as dependency for the user (we set Python only as dependency).

I understand that the Fluid Server requires Node.js.

Are there any plan or ways to have a Python implementation of the Fluid server?

SamBroner commented 3 years ago

Hey @echarles, good to hear from you!

The Fluid server could be written in any language. We use NodeJS because it's what the rest of the code base uses and that makes context switching easier. We don't have plans to rewrite the reference server or tinylicious at this time.

The client code (loader, runtime, containers, etc) are in JavaScript because the dynamic deployment of JS code makes eventual consistency much easier for us (connected clients are always on the same version.) We don't have plans to support a Python implementation of this.

Does that answer your question? My guess is that you're also concerned with the client code.

echarles commented 3 years ago

Thx @SamBroner Yes, it answers my question. Feedback from a potential user is that an existing application will want to interact with what is going on in the collaborative session (e.g. get current status of the merged documents, know who is collaborating...). I have seen other projects moving/rewriting their server part in rust which would allow to bind from e.g. python. I guess this in not either in the Fluid roadmap atm. Worth to consider? On our side (Juypyter), this specific issue to not being able to interact from our existing Python to the Fluid sever might be a deal-breaker.

SamBroner commented 3 years ago

@echarles The Fluid Server is (mostly) written such that the client to client payload could be entirely encrypted in transit. There isn't really a server side binding to latch onto. The server is a thin layer around Kafka, our total order broadcast, that adds some perf improvements, long term storage, and tenancy features.

For the scenario of Python Server code to Fluid, my initial suggestion is a JS engine hosting a headless Fluid client. Although I can see why this isn't ideal. We've also experimented with lambdas directly on the kafka stream, but they don't benefit from seeing merged client state they just see the stream of messages.

What is the specific data/metadata about the session you're looking for?

echarles commented 3 years ago

What is the specific data/metadata about the session you're looking for?

It is around the content REST API and the cell execution WebSocket messages. We would prefer to drive all these via the CRDT channel, but to do that, we need a connection with the Fluid client/server and our existing Python endpoint.

For now we are still experimenting and we may find while developing something that it is easier than expected. Thx for inputs so far. I will come back here when we have concrete questions.

kurtb commented 3 years ago

@echarles are you looking for the Python/Rust Fluid Service so that the existing Jupyter service can host the Fluid service side directly? i.e. no need to run Fluid in Docker (etc...) as part of launching Jupyter?

Or for the Python kernel (or other) to become a collaborative agent itself against the session? As opposed to collaboration happening inside the browser?

echarles commented 3 years ago

@kurtb

are you looking for the Python/Rust Fluid Service so that the existing Jupyter service can host the Fluid service side directly?

Yes, exactly, so the Jupyter service can interact easily with the Fluid service

i.e. no need to run Fluid in Docker (etc...) as part of launching Jupyter?

Yes, we don't want to ask Jupyter users to install node.js nor docker

Or for the Python kernel (or other) to become a collaborative agent itself against the session? As opposed to collaboration happening inside the browser?

The interaction between the user and the kernel goes via the server. We think server is the place where the RTC collaboration should happen. Kernel interacting directly in a RTC session without needing a server is a nice idea, but not in the roadmap for now.

SamBroner commented 3 years ago

@echarles, can you remind me (and possibly other readers on this thread) how multi-user interaction works in a Jupyter RTC session? I believe this conversation was started at https://github.com/jupyterlab/rtc/issues/80#issuecomment-703225019 and there are more resources here https://github.com/jupyterlab/rtc/pull/88.

A question I had: are multiple users working against one Python runtime in the server?

One great/useful artifact of this discussion would be diagraming where collaboration happens, what the source of truth is for a Jupyter RTC session, and what the language & environment requirements are at the client and servers.

Also, Happy holidays!

echarles commented 3 years ago

@SamBroner For now, jupyter server is single user. We are designing to make it multi-user with pluggable identity provider. That is a big work with moving target, especially when we put RTC into the picture. The diagrams will for sure help (still working on this).

kurtb commented 3 years ago

The service side of Fluid is fairly light - so could definitely be written in either Python directly - or something that binds well to Python like Rust/C - but obviously it's a work item. I think you've seen https://medium.com/swlh/how-a-fluid-framework-service-works-c82fe9f78ae9 and https://medium.com/@kurtberglund/fluid-framework-snapshots-9099f91bb606 but they give a bit of context as to what the service itself does.

The JavaScript code in the browser is where the heavy lifting happens. And like Sam pointed out earlier the choice of JavaScript is very deliberate since you can dynamically define new data types, components, etc...

The server itself never loads the collaborative state. It just orders the messages and then saves snapshots. This keeps it cheap and light. But if you want to access current values presents problems. Unless what is in the snapshot is enough. With some work the snapshot could be the ipynb too.

Another option some users do is to proxy to a stateful system and bring the results back into the collaboration. From the bit I've used Jupyter I could imagine having the text of a cell being a collaborative item maintained in JavaScript. When I then execute the cell I make a call to the kernel and then bring the results back into the collaboration. You could use leader election to elect a single user to do this. Or allow anyone to perform the action.

But I think if you had a pluggable Fluid service that would work with your Jupyter server you could get the kernel interaction to work. Looking forward to the diagrams.

echarles commented 3 years ago

The server itself never loads the collaborative state. It just orders the messages and then saves snapshots. This keeps it cheap and light

Is https://github.com/microsoft/FluidFramework/tree/main/server/routerlicious/packages/routerlicious/src the place to look at to better understand the current server implementation in node.js

The diagrams for Jupyter will help to understand the current and target architecture. Any such diagram for Fluid which is also a fairly evolved system as far as I can see?

kurtb commented 3 years ago

@tanviraumi might know where the most up to date version is - but this image still gives a good feel for what's happening in the service.

The names are described in more detail here.

All of them are lambda functions tied together via a data bus. For the most throughput and scalability we go with something like Kafka. But tinylicious instead does everything in memory on a single node. I'd expect something along the lines of tinylicious is what a jupyter server would embed inside itself.

In the diagram clients represent both browser based clients as well as service side ones. These clients load/run the Fluid runtime and then talk to the service for ordering/snapshots. When I mentioned the kernel needing Fluid access before I was partly wondering if it would ever want to be a Fluid client itself.

vladsud commented 3 years ago

This is not really in our plans. This is great discussion and maybe something we get to some day, but we are trying to keep our issue list relevant / clean of discussions, i.e. only keep things that we realistically could do in reasonable amount of time (let's say 6 months).

ghost commented 3 years ago

Because this issue is marked as "won't fix" and has not had activity for over 3 days, we're automatically closing it for house-keeping purposes.