I’m trying to design something like Drab but in which client and server share the state and can both apply changes to the state. State would be represented as JSON or something equivalent. I’d like to support maps and lists.
I keep all state on the server, and the client can’t even touch the state directly. It can only send events to the server so that the server approves of the changes and broadcasts them back.
Currently I have a problem when editing lists. List operations are identified with elements. It makes sense to say: “delete element 1” or “delete element 2”.
When an Item is deleted, the server updates the list, and broadcasts the change to the client. The UI is only updated after the client receives the server’s response.
This is simple, but if the user deletes two elements of the list on the client very quickly, before the server has time to send back to the client the new state, then the operation will have changed meaning, that is, I’ll be removing a different element form the one I wanted. Concretely: if I send: “delete 1” and “delete 2”, the server will delete element 1, then element 3 (because the old element 2 would have moved to position 1 and the old element 3 would have moved to position 2).
I can solve this by selectively blocking parts of the UI, but I’d like to avoid this for several reasons.
It seams like the solution would be to have some kind of replicated datastructure on the client and server that could interpret these changed correctly. From what I’ve read, CRDTs seem like a viable solution, and scale to several clients connected to the same server.
But maybe actually need something simpler, like Operational Transformation (OT); I think there are OT algorithms for JSON.
EDIT: maybe this is more general discussion than just Phoenix; the core details are actually independent of phoenix, so maybe this should be moved? I don’t know.