I’ve been thinking of realtime collaboration on Phoenix. The most obvious case is text editing (both rich text and plain text) bit there is a lot of potential for rocher datatypes, like JSON documents.
SharDB is a Javascript framework running on NodeJS that allows for real-time collaboration in editing JSON documents, with facilities for text editing as a special case. It uses Operational Transformations (OT) with a client-server architecture (not peer-to-peer, that doesn’t really work very well in real life). I think it would be cool to have this in Phoenix.
Currently, there are Elixir libraries that handle OT for plaintext and rich text, although none of those libraries ship with a production-quality server or client. The library for plain text OT does ship with a server, but not with a client, and the implementation of the server is not complete.
There isn’t yet an implementation of OT for JSON documents in Elixir, but the implementarion used by ShareDB seems easy to port (the transformation function is quite stupid and inefficient, but it seems to get the job done).
Instead of OT, some people advocate CRDTs, but they have some important disadvantages in practice. They have a much higher memory overhead (and sometimes a higher bandwidth overhead) and they don’t resolve conflicts. OT with a central server has low overhead and gives us a canonical document (the one that lives on the server) at each moment in time.
This leaves us with the taks of:
-
Writing a client using something like Phoenix channels
-
Implementing the network protocols. It’s possible to opimize them a lot when compared to what ShareDB does. ShareDB uses JSON, which for small events like keypresses wastes bandwidth like crazy. Some easy savings could be achieved by using MsgPack instead of JSON, but I suspect we can do better with even more compact transmission formats.
-
Porting OT for JSON documents from ShareDB. This is important because JSON can describe a lot of types of variable length documents.
-
Writing a generic OT server onto which one can plug the different OT types. This part is independent from phoenix, even if it ends up using Channels to communicate with the outside world.
What would this be useful for? Well, first for “normal” collaborative editing. Think of a document that can be edited by more than one person. Or even a JSON tree of documents that can be esited by more than one person.
But there are other advantages. Think of something like Drab. Drab.Live makes it possible to sync client and server. But it can get you in problems if you edit the state on the client and server concurrently. You get the semantics not of collaborative editing but of Last Write Wins, which is not desirable. If you have OT, you can edit the state on the client and server concurrently ( the fact that other users can esit the state too is a just a nice bonus). This could pave the way for real isomorphic apps in which the state is shared by the client and server and can be operated on by both of them.
Elixir makes it easy to deal with the kinds of servers required here (just spin up a genserver per document and listen to operations, possibly persisting the oeprations womewhere, like an ETS table). The main obstacle here is the fact that a lot of code still needs to be written. I wonder of users here would like to collaborate on this.