A simple way to build collaborative web apps
craig_asp 2021-08-17 14:46:16 +0000 UTC [ - ]
We gave up on the websocket part and implemented basic polling, because they were not supported by App Engine at the time (things might have moved on since then, which is a couple of years ago). Yet, for a note/todo/habit tracking app, it simply doesn't need to be real-time from our experience.
Have a play at https://www.mindpad.io/app/. You can see how it works if you open up the web app in two incognito tabs, or on an iPhone and the web.
albertgoeswoof 2021-08-17 21:50:12 +0000 UTC [ - ]
It never really took off in the mainstream - I think because it was before many developers really trusted JS on the server, and a "full stack" framework is quite a big commitment for a team to shift to. Also most CRUD apps don't need real time collab.
I remember being amazed when changes were instantly propagated between my phone and laptop browsers with almost zero lag. This was the demo that sold it for me https://www.youtube.com/watch?v=MGbmW9bwJh4
thezjy 2021-08-18 01:34:49 +0000 UTC [ - ]
valzam 2021-08-18 02:17:54 +0000 UTC [ - ]
eatonphil 2021-08-17 15:27:12 +0000 UTC [ - ]
There are a couple of open-source CRDT libraries that provide both clients and servers (yjs [0] and automerge [1] are two big ones for JavaScript I'm aware of).
My basic assumption is that as long as you put all your relevant data into one of these data structures and have the CRDT library hook into a server for storing the data, you're basically done.
This may be a simplistic view of the problem though. For example I've heard people mention that CRDTs can be space inefficient so you may want/have to do periodic compaction.
feanaro 2021-08-17 18:52:35 +0000 UTC [ - ]
eatonphil 2021-08-17 18:58:18 +0000 UTC [ - ]
At the very least, the automerge maintainers seem to be very actively tackling performance problems.
josephg 2021-08-17 23:15:02 +0000 UTC [ - ]
They’re working on it, but it’ll be awhile before automerge gets close to Yjs in terms of performance.
aboodman 2021-08-18 00:13:49 +0000 UTC [ - ]
brunoqc 2021-08-17 16:15:28 +0000 UTC [ - ]
eatonphil 2021-08-17 16:19:08 +0000 UTC [ - ]
tabtab 2021-08-17 20:42:48 +0000 UTC [ - ]
RDBMS A.C.I.D. and transactions are also capable of much of the same.
idontevengohere 2021-08-17 14:58:23 +0000 UTC [ - ]
valzam 2021-08-18 02:19:56 +0000 UTC [ - ]
That being said you can totally implement collab without CRDTs and if you don't particularly need offline it should be easier.
paulgb 2021-08-17 18:58:55 +0000 UTC [ - ]
nesarkvechnep 2021-08-17 15:58:05 +0000 UTC [ - ]
deathtrader666 2021-08-17 19:16:02 +0000 UTC [ - ]
thezjy 2021-08-18 01:48:19 +0000 UTC [ - ]
- WebSocket (and Phoenix Channel) is just a communication method. To maintain consistency and resolve conflict, you need something like Replicache.
- CRDTs are more suitable for p2p scenario while Replicache works better for client-server apps.
- Phoenix's Presence is built with CRDT but it's just a single feature, not a general CRDT toolkit.
The thread: https://twitter.com/aboodman/status/1410441402366922762
ec109685 2021-08-18 07:09:24 +0000 UTC [ - ]
Wowfunhappy 2021-08-17 19:57:08 +0000 UTC [ - ]
> People who love "native apps" can complain about Electron all they want—but there's simply no replacement for the real-time collaboration offered by web-based apps like Figma!
As someone who's not exactly thrilled with Electron and its memory usage—is there a reason the two go together? Is there a reason we can't build collaborative apps in Cocoa and GTK? I think these systems are awesome, I just think they'd be even better if they weren't also running full web browsers!
SilverRed 2021-08-18 05:02:13 +0000 UTC [ - ]
This is reason enough. Already you now have to build the UI twice because there is no GUI framework that actually looks good on all OSs. You see this all the time where apps made on linux but technically work on macos just work terrible or look super ugly on macos.
You also have to remember windows, ios and android. When you build something targeting web browsers you only have to worry about screen sizes rather than OSs.
BackBlast 2021-08-17 20:47:45 +0000 UTC [ - ]
It's just much much easier and cost effective to build a single code base and hit many many targets platforms with it.
Computing history has also shown that publishing efficient lean software doesn't help in the market. At least not over time to market, getting the key features right, and your ongoing costs.
rl3 2021-08-17 20:20:53 +0000 UTC [ - ]
To answer your question, collaborative apps ideally need to target the widest possible audience. Barring a massive budget, the best way to accomplish this is to also have a singular compile/build target. In most cases, that’s the web platform.
Wowfunhappy 2021-08-17 21:22:01 +0000 UTC [ - ]
If Sketch had had Figma's collaboration features, we wouldn't have switched. But during the pandemic it was necessary.
timwis 2021-08-17 14:34:10 +0000 UTC [ - ]
tmikaeld 2021-08-17 14:37:12 +0000 UTC [ - ]
"This means that transactions are guaranteed to be applied atomically, in the same order, across all clients. Further, all clients will see an order of transactions that is compatible with causal history. Basically: all clients will end up seeing the same thing, and you're not going to have any weirdly reordered or dropped messages."
[0] https://doc.replicache.dev/design
Note: There's more in their links, but the linked sites are down..
btown 2021-08-17 15:57:03 +0000 UTC [ - ]
See also the commentary here: https://doc.replicache.dev/guide/local-mutations
This sounds a lot like Operational Transform but without the transform part - it assumes that locally applied mutations can be undone and rebased without user interaction. But I feel like the Google Wave team would have a lot of objections to the idea that this can just be ignored. If your state is just a group of key value stores where last write wins and everyone can agree on who's last, that's fine, but text/token streams require a notion of transformation that I'm worried Replicache simply glosses over.
Chris_Newton 2021-08-17 18:56:24 +0000 UTC [ - ]
For example, suppose we have an edit/delete conflict, where two clients concurrently interact with the same entity in your data model. In a simple case, we can decide to “resurrect” the affected entity and apply the edit, which is the option that never results in significant data loss and so might be a reasonable behaviour if no user interaction is involved.
Now, what if there were other consequences of deleting that entity? Maybe the client that deleted the entity then created a new entity that would violate some uniqueness constraint if both existed simultaneously. Or maybe it wasn’t the originally deleted entity that would violate that constraint, but some related one that was also deleted implicitly because of a cascade. How should we reconcile these changes, if simply allowing either one to take precedence means discarding data from the other?
At least if all clients are communicating in close to real time, it’s unlikely that any one of them will diverge far from the others before they get resynchronised, so the scope for awkward conflicts is limited. But in general, we might also need to support offline working for extended periods, when multiple clients might come back with longer sequences of potentially conflicting operations, and there’s no general way to resolve that without the intervention of users who can make intelligent decisions about intent, or at least a set of automated rules that makes sense in the context of that specific application. And in the latter case, we’d still probably want to prove that our chosen rules were internally consistent and covered all possible situations, which might not be easy.
aboodman 2021-08-18 08:06:23 +0000 UTC [ - ]
Exactly. This is why Replicache expresses change as high-level operations, like createPost or deletePerson that are application-defined.
Replicache doesn't try to automatically merge the effects of concurrent mutations, it just replays the mutations in the same order on each client. It's up to the implementation of the mutation to decide what the correct result is, and that answer can and often does change when the mutation is replayed on top of different states.
Because Replicache mutations are atomic, applications can also enforce invariants such as uniqueness or even more complex app-level invariants.
Imagine, for example, a calendaring application. An application built with Replicache can enforce the invariant that a room is only booked by one event in one time slice even under concurrent edits, just using normal programmatic validation. It's hard to do this kind of thing with CRDTs or other approaches to automatic merging because the data model knows nothing about the application's constraints.
It's a pretty simple-minded system, actually, but our experience is that it is a nice way to think about these problems and provides good results for many types of data, in particular structured data.
aboodman 2021-08-17 22:23:09 +0000 UTC [ - ]
Now, it is true that OT is considered the gold standard for certain kinds of collaborative editing, in particular unstructured text. But CRDTs are quickly catching up and I believe that any CRDT should by definition be implementable on top of Replicache.
Its also quite a lot easier to implement a Replicache backend than an ot backend.
josephg 2021-08-17 23:21:58 +0000 UTC [ - ]
The result is we need way less complexity in the browser, or in applications. And still get all the advantages crdts bring - namely, no need for a central server acting as the source of truth.
aboodman 2021-08-18 08:12:43 +0000 UTC [ - ]
I think for many customers the authoritative server is an advantage. It's useful in SaaS apps for the server to be able to override the clients, for all kinds of reasons -- antiabuse, authorization, extra validation rules, or just fixing bugs.
josephg 2021-08-19 01:03:46 +0000 UTC [ - ]
- A fast and well written CRDT that works in p2p networks should also work great for server-to-server replication in a data center (or across data centers).
- OT algorithms designed to work with centralized servers are simple, efficient, easy to code up and easy to work with. And they provide a really nice API for local applications to do IPC. CRDT libraries can expose OT endpoints just fine.
I'm still not 100% sure about what the best approach is in the P2P case. Embedding (/ linking) a CRDT library into every application would also work fine, but its complicated to get everything working across languages. And harder to update. The other option is running a single system / applicatoin wide CRDT-like service which manages credentials, that applications talk to like LSP / D-Bus. In that case, applications can just talk OT (which is much simpler).
Either approach would work.
tmikaeld 2021-08-17 16:44:47 +0000 UTC [ - ]
tabtab 2021-08-17 20:46:42 +0000 UTC [ - ]
Zealotux 2021-08-17 14:37:29 +0000 UTC [ - ]
Gabrielwxf 2021-08-17 14:37:19 +0000 UTC [ - ]
amelius 2021-08-17 21:34:27 +0000 UTC [ - ]
tommoor 2021-08-17 14:47:29 +0000 UTC [ - ]
BackBlast 2021-08-17 20:40:24 +0000 UTC [ - ]
This route seems like a lot of extra work for pretty similar functionality.
winrid 2021-08-18 03:23:30 +0000 UTC [ - ]
Also, integrations use polling: https://github.com/FastComments/fastcomments-integrations/tr...
The integrations work kind of like DB slave replication. They do an initial sync and then maintain state via the event stream.
theanirudh 2021-08-18 04:36:31 +0000 UTC [ - ]
Zealotux 2021-08-17 14:45:48 +0000 UTC [ - ]
ZeroCool2u 2021-08-17 15:28:20 +0000 UTC [ - ]
Am I wildly off base here? Is it just that middle tier jump to over 10k that is a no go?
Again, I don't have a horse in this race or even my own startup, just trying to understand if my own judgement is way off.
Zealotux 2021-08-17 15:45:32 +0000 UTC [ - ]
memco 2021-08-17 16:56:31 +0000 UTC [ - ]
[Error] Could not connect to the server.
[Error] Fetch API cannot load https://damp-fire-554.fly.dev/replicache-pull?list_id=kx1I-gXPWwOxU9teRUJ_c due to access control checks.
[Error] Failed to load resource: Could not connect to the server. (replicache-pull, line 0)
Safari 14.2 on macOS 10.15.7.
thezjy 2021-08-18 03:34:37 +0000 UTC [ - ]
https://stackoverflow.com/questions/63141448/safari-fetch-ap...
davedx 2021-08-17 17:06:53 +0000 UTC [ - ]
mrkurt 2021-08-17 17:28:05 +0000 UTC [ - ]
I work on Fly.io, but there's very little vendor lock in here. We can't afford to lock people in, we're too small. We need to make their existing stuff work with zero friction.
sirtimbly 2021-08-17 20:48:13 +0000 UTC [ - ]
SilverRed 2021-08-18 05:11:04 +0000 UTC [ - ]
aboodman 2021-08-17 21:22:52 +0000 UTC [ - ]
thezjy 2021-08-18 01:28:56 +0000 UTC [ - ]
aboodman 2021-08-18 08:14:42 +0000 UTC [ - ]
Gabrielwxf 2021-08-17 14:48:37 +0000 UTC [ - ]
Excellent write. It would be great to know why CockroachDB failed your needs.
thezjy 2021-08-18 01:29:37 +0000 UTC [ - ]
ec109685 2021-08-18 04:20:33 +0000 UTC [ - ]
Definitely interested in understanding end user benefit of the distributed database given one of purposes of library is to hide write latency and there needs to be coordination for every write.
awinter-py 2021-08-18 00:53:01 +0000 UTC [ - ]
web apps are sorely lacking a core storage technology
whoever gets their first may not make a lot of money but they'll be more influential than react (because the schema design will penetrate native dev as well)
sambroner 2021-08-17 15:37:55 +0000 UTC [ - ]
The libraries are also not functionally equivalent. Some use OT, some use CRDTs, some persist state, some are basically websocket wrappers, fairly different perf guarantees in both memory & latency etc. The very different capabilities make it complicated to evaluate all the tools at once.
Obviously I'm partial the Fluid Framework, but not many realtime coauthoring libraries have made it as easy to get started as Replicache. Kudos to them!
A few solutions with notes...
I should add... I talk to many folks in the space. People are very welcoming and excited to help each other. Really fun space right now.nikodunk 2021-08-17 21:43:23 +0000 UTC [ - ]
Built a Google Docs like rich text collaborator for a client on Express/Psql and React. Worked like a charm. The hardest part was dealing with ports on AWS to be honest.
BackBlast 2021-08-17 22:54:19 +0000 UTC [ - ]
PouchDB+CouchDB work well out of the box with minimal fuss for open pieces you can just plug into this role. PouchDB handles the client's state persist and replication on the client, couchdb is the reliable cloud service you can replicate to.
Meteor, at least their pre-apollo stack had realtime collab type features with their mini-mongo client and oplog tailing.
winrid 2021-08-18 03:10:08 +0000 UTC [ - ]
I know of one big company using it extensively, hundreds of millions of messages a day! :)
moralestapia 2021-08-18 03:39:44 +0000 UTC [ - ]
Like a Google Docs kind of thing or w?
winrid 2021-08-18 04:42:24 +0000 UTC [ - ]
vyrotek 2021-08-17 19:25:20 +0000 UTC [ - ]
Maybe it's just me, but it has a SignalR + Orleans sort of vibe to it when I think about the types of problems it solves. I will definitely be digging into this a bit more.
moralestapia 2021-08-18 03:44:14 +0000 UTC [ - ]
1: https://gun.eco/