yjs / y-websocket

Websocket Connector for Yjs
https://docs.yjs.dev/ecosystem/connection-provider/y-websocket
MIT License
492 stars 255 forks source link

Extraneous updates where origin == null when using full reload #157

Open TeemuKoivisto opened 10 months ago

TeemuKoivisto commented 10 months ago

Checklist

Describe the bug So recently I had to debug a rather complicated bug in my yjs server. What happens is, I am loading updates from DB but the list is only partial. Which maybe wouldn't be so bad except that the client keeps generating extraneous updates on full reload thus overwriting the document in the DB.

This is a rough rundown of what's happening:

  1. Client sends syncstep1 & awareness
  2. Server fetches the updates, when doc is loaded sends syncstep2 & awareness
  3. Client applies the update and sets itself synced
  4. this.doc.on('update', this._updateHandler) triggers but the update is skipped since origin is the provider
  5. However, at this point the Y.Doc generates three additional updates with origin == null which are sent to the server
  6. Server receives them and happily commits them to the DB
  7. Doc has been overwritten

What makes this bad even when I am fetching the complete list are the three additional updates which are inserted every time the doc is loaded. The line in question is here https://github.com/yjs/y-websocket/blob/02f691d89c8cfea884d9f9fa98f0ff192b0eb7d9/src/y-websocket.js#L260 for which I added a check in my own fork of y-websocket where I skip them if (origin !== this && origin) {. However, this has introduced another bug - inconsistent state between client and the server.

I am not necessarily sure if this is a problem with core "yjs" package but I hope this is addressed regardless. I think it is quite serious issue with rather hard to debug complications. Also, as a side-note, adding "type": "module" to the package.json would be nice since Vite really doesn't like importing y-websocket otherwise.

To Reproduce

  1. git clone https://github.com/TeemuKoivisto/yjs-demos
  2. cd demo-server && npm i && npm start
  3. cd prosemirror-versions && npm i && npm start
  4. Open http://localhost:5173 (or what vite tells you)
  5. Open browser console, sometimes the extraneous updates with origin == null don't appear but doing a full refresh (Shift+Cmd+R in macOS) should cause it

EDIT: it appears to happen more often with older "yjs" version (13.4.x) and now, as I updated both the client and server to latest 13.6.8, it happens every second or so regular refresh Cmd+R and every hard refresh Shift+Cmd+R

Expected behavior When doc is loaded, the client should not generate any more updates than necessary

Environment Information

Tested with 2 year older versions and it seems to be happening with them as well. My server is using yrs so I am highly confident the bug is with the client-side code.