automerge / automerge-classic

A JSON-like data structure (a CRDT) that can be modified concurrently by different users, and merged again automatically.
http://automerge.org/
MIT License
14.75k stars 466 forks source link

Simultaneous changes from peers freezes syncing #367

Closed skokenes closed 3 years ago

skokenes commented 3 years ago

I am using automerge@1.0.1-preview.1 in a setup with a centralized server that syncs 2+ peers to each other via a middleman "hub" node.

I have been testing a scenario where 2 peers are making a continuous stream of edits at the same time via the hub. I've found the syncing is completely unstable in this scenario, causing the syncing to stall out and freeze up completely.

I've replicated this scenario with a simple browser app using two peers and a hub communicating via the window object. You can find this code at https://github.com/skokenes/automerge-sync-test You can also see it running at https://codesandbox.io/s/am-syncing-test-07x4z

In this example, each peer has a button you can press that will cause the peer to insert a character once every 500ms. When only 1 peer is making these changes, the syncing works fine as seen in this video:

https://user-images.githubusercontent.com/5554373/118061123-50e0aa80-b362-11eb-9dec-9c0f6346f93f.mov

However, when both peers are inserting characters every 500ms, the syncing freezes as seen here:

https://user-images.githubusercontent.com/5554373/118061194-740b5a00-b362-11eb-897b-741ddbc12834.mov

skokenes commented 3 years ago

Here is a nodeJS script version of the issue that you can run: https://gist.github.com/skokenes/aa73c3d2f659728783bfc2943b45d7ef

On my machine, timing how long it takes 15 changes at a rate of 1 change per 500ms from just 1 peer: ~7s, as expected. When both peers are making 15 changes at that same rate, it takes ~60s for the syncing to finish! If you bump the number higher, you will see the performance degrade even further. I believe it might be non-linear

ept commented 3 years ago

Hi @skokenes, thank you for the nice self-contained test case, which allowed me to reproduce the issue easily. I think I have fixed it in #369 (a quite embarrassing bug). Could you test it please?