The setting is, multiple frontend and a server are sharing a yjs doc. At certain time A, a frontend may send a request to the server, asking the server to do something with the snapshot of time A.
I’ve read Locking using Yjs - #4 by dmonad and learned that retrieving a specific snapshot is impossible, so I am seeking an alternative. Is it possible to check if server still holds snapshot of time A, so if the server holds an earlier or later snapshot, the request could be rejected. Is there any token or something that can do that?
Suppose I have a tree structure (a combination of ymap, yarray and other primitive data structures) shared across multiple clients. Here “snapshot” means an abstract state of the tree at certain time at a specific client, not any specific yjs class name.
What I want to achieve here is that, in client A, at A’s timestamp TimeA, a request is sent from A to B, in order to perform some actions with the tree. Since the tree may be very large, I will not send the whole tree, instead just send a “timestamp” indicating it is TimeA at client A. When client B received the “timestamp”, since there is no locks, the specific state could be different from the state at client A’s time A. I want a mechanism to tell if the state exactly matches the state at client A’s time A or not.
You could actually use Yjs snapshots to achieve this. Compute Y.snapshot(ydoc) on the client, and send it along with the change you want to perform. The compare Y.snapshot(serverYdoc) with whatever you created on the client.
Thank you Kevin, I learned something and will put it here, correct me if I misunderstand anything.
Y.snapshot is built from the history of a doc at specific client (call it client A), it is constructed as all the client ids that appeared in the history and their version id and some delete sequence lengths. In a word, snapshot stores only metadata so it could be pretty small. When comparing to the whole doc, the payload size of a snapshot could be ignored.
When snapshot is sent to another client to rebuild doc, the client will match the snapshot’s client id/each id’s version/other metadata to reconstruct the doc from its history.
While this mechanism is efficient, in certain scenarios it may fail to reconstruct. For example, when client A send a snapshot which is too old for client B, B may already garbage collect the related metadata and cannot retrieve the information needed back. Or, when A’s snapshot is newer than B’s history, B will fail to reconstruct it, too.
A Yjs snapshot does not contain any content. It describes the state of a Yjs document in time. So if snapshot1 equals snapshot2 then both documents contain the same content.
Your original question was how you can check if the local document matches the remote document. Comparing snapshots is the best approach to achieve this.
Indeed, I am asking that, but my original case is:
At client A’s certain time TA, a frontend may send a request to the server, asking the server to do something with the snapshot of client A’s time TA.
Before, I thought it is not achievable because there is no guarantee that when the request is received by client B, what the state of client B is, then I ask a simpler question to compare snapshots. Now with Y.Snapshot, I find the original case could also be achieved by reconstruct client A’s time TA snapshot at client B, in most of the cases it works, right?