Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Snapshot Hotfix: Merge targetSV with localYJS_SV before writing into localYJS_SV #177

Merged
merged 3 commits into from
Feb 13, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions src/backend/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ export async function bootstrapWorkspace(opts: {

const localTimestamp = await persistStore.get('snapshotTimestamp')

const timestampInterval = 86400000 //24hr
const timestampInterval = 900000 //15min //86400000 //24hr
if (!localYJSUpdate || !localTimestamp || Date.now() - NNI.decode(localTimestamp) > timestampInterval) {
const interest = new Interest(snapshotName, Interest.CanBePrefix, Interest.MustBeFresh)
try {
Expand All @@ -232,19 +232,29 @@ export async function bootstrapWorkspace(opts: {
await persistStore.set('localSnapshot', snapshotData)

// State Vector Merge
// Extract state vector from the snapshot
const aloSyncKey = '/8=local' + nodeId.toString() + '/32=sync/32=alo/8=syncVector'
// TODO: SVS parsing check TLV type. Currently assumed as /54=.
// TODO: SVS parsing check TLV type. Currently assumed as /54=, using ".value" to extract the encoded state vector
let targetSVEncoded = targetName.at(-1).value
// load local state first with the snapshot.
await persistStore.set('localState', targetSVEncoded)

// Merge the SV with the local one so that when SyncAgent starts up,
// Merge targetSV with local YJS state vector, then save to local YJS save
const localYjsSVEncoded = await persistStore.get('localState')
let mergedYjsSVEncoded = targetSVEncoded //default case
if (localYjsSVEncoded) {
const localYjsSV = Decoder.decode(localYjsSVEncoded, StateVector)
const targetSV = Decoder.decode(targetSVEncoded, StateVector)
targetSV.mergeFrom(localYjsSV)
mergedYjsSVEncoded = Encoder.encode(targetSV)
}
await persistStore.set('localState', mergedYjsSVEncoded)

// Merge the SV with the local ALO one so that when SyncAgent starts up,
// it replays the local updates (in local storage), starting from snapshot's vector.
const localSVEncoded = await persistStore.get(aloSyncKey)
if (localSVEncoded) {
const localSV = Decoder.decode(localSVEncoded, StateVector)
const localAloSVEncoded = await persistStore.get(aloSyncKey)
if (localAloSVEncoded) {
const localAloSV = Decoder.decode(localAloSVEncoded, StateVector)
const targetSV = Decoder.decode(targetSVEncoded, StateVector)
targetSV.mergeFrom(localSV)
targetSV.mergeFrom(localAloSV)
targetSVEncoded = Encoder.encode(targetSV)
}
await persistStore.set(aloSyncKey, targetSVEncoded)
Expand Down