I've also used it to synchronize content for local multi-window editing applications: each window is its own process but routes through one "coordination" process to ensure consistent ordering.
Easily solves some cross-process concurrency issues.
We did a few days of CRDT investigation along with the other techniques and decided the juice wasn't worth the squeeze when we found a simpler solution to our problem.
That being said, we've actually retained a CRDT-like implementation in our codebase and have been considering moving shapes (which have a slightly different set of tradeoffs) to that model.
I don’t quite understand the “funnel” section. Users see some change local immediately (S1->S2). And all users send all commands to the host. The host then effectively chooses the sort order and broadcasts back.
So does the initial user effectively rewind and replay state? If action applied to S1 was actually from another player they rewind to S1 and apply the sequence?
How many state snapshots do they need to persist? There was no mention of invertible steps.
I feel like I’m missing a step.
We have some actions which happen when saving config UI which don’t really need realtime sync when “save” is pressed and we treat them more like a normal POST request (e.g. we wait for full commit before rerendering). The form fields are kinds a built-in imposter.
For state snapshots we only do big ones. The “full save” that happens every 25 actions or so. These aren’t generally used for reverting people.
So it kinda works like:
1. Do I have an outstanding imposter? If so read from it.
2. Otherwise read from the committed state.