automerge / trellis

Trello clone / sample app for Automerge persistence library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Syncing gets stuck when clicking a new document in Documents list

adamwiggins opened this issue · comments

Steps to reproduce:

  1. Run this script
#!/bin/sh

mkdir ~/alice
rm ~/alice/*.trellis
mkdir ~/bob
rm ~/bob/*.trellis

PORT=4200 INTRODUCER= SAVE_DIR=~/alice NAME="Alice" npm start &

sleep 5
echo '-------'
echo
echo "Document -> New in the Alice client. Press enter when done..."
read

PORT=4201 INTRODUCER=localhost:4200 SAVE_DIR=~/bob NAME="Bob" npm start &
  1. After the Alice client launches, execute Document -> New
  2. Press enter in the console
  3. From the Bob client, click on the document that Alice is in (in the screenshot: silver-shanghai-8)
  4. Bob client gets stuck with a blank board and no changes that Alice make are reflected

screen shot 2017-06-28 at 21 28 14

Possibly important clue: if you wait until Bob is already connected to Alice at the time Alice creates the document, syncing works fine. The document has to be created before Bob connects to Alice.

I narrowed down the problem to this: Alice doesn't send her deltas to Bob because her record of Bob's vector clock is null, but Bob doesn't send broadcast his vector clock unless he receives deltas. My fix in aMPL was to broadcast our vector clock whenever we change documents (after we broadcast our new docId):

        if (!this.deltaRouter || action.type === "NEW_DOCUMENT" || action.type === "OPEN_DOCUMENT" || action.type === "FORK_DOCUMENT") {
          this.network.broadcastActiveDocId(this.state.docId);
 +        if (this.deltaRouter) this.deltaRouter.broadcastVectorClock();
        }
  
        this.deltaRouter.broadcastState();
```

I'm still not sure why Alice doesn't have Bob's vector clock, still looking into whether that's expected or not for a peer who opens a new document.

Alright, after some more digging here's what I figured out about why Alice doesn't have Bob's vector clock: Alice ignores messages from Bob unless they're about the same docId that Alice is on (makes sense because you wouldn't want to store Bob's vector clock for some other docId anyway).

When Bob opens up Alice's document, he does broadcastActiveDocId which only sends docId and knownPeers but not his vector clock. Alice gets this broadcast from Bob, doesn't ignore it because it has the same docId that Alice is on, but then ignores it anyway because there's no vector clock in the message. In my current patch, we just send a second message to Alice with our vector clock which triggers the delta exchange. That seems fine to me, unless broadcastActiveDocId should just do it on the first message.

That's a good fix. I think we probably don't want to entangle the ephemeral document status and the vector clock / delta mechanisms but the whole thing really should be rethought to support multiple documents properly instead of this kluge.