From 66adc2d597cae928c23226d915b3a8019e253fd0 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 21 May 2022 12:47:59 +0100 Subject: [PATCH 1/3] prevent overlapping sync accumulator persists add a flag to stop the sync worker trying to persist to indexeddb if there are already persists in flight. accumulates user presence updates in RAM to stop them being lost if the persist is skipped. hopefully fixes https://github.com/vector-im/element-web/issues/21541 --- src/store/indexeddb-local-backend.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/store/indexeddb-local-backend.ts b/src/store/indexeddb-local-backend.ts index a7a7e257418..91d0e6a44bf 100644 --- a/src/store/indexeddb-local-backend.ts +++ b/src/store/indexeddb-local-backend.ts @@ -127,6 +127,8 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend { private db: IDBDatabase = null; private disconnected = true; private _isNewlyCreated = false; + private _isPersisting = false; + private _pendingUserPresenceData: UserTuple[] = []; /** * Does the actual reading from and writing to the indexeddb @@ -401,11 +403,22 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend { public async syncToDatabase(userTuples: UserTuple[]): Promise { const syncData = this.syncAccumulator.getJSON(true); + if (this._isPersisting) { + logger.warn("Skipping syncToDatabase() as persist already in flight"); + this._pendingUserPresenceData.push(...userTuples); + return; + } else { + userTuples.unshift(...this._pendingUserPresenceData); + this._isPersisting = true; + } + await Promise.all([ this.persistUserPresenceEvents(userTuples), this.persistAccountData(syncData.accountData), this.persistSyncData(syncData.nextBatch, syncData.roomsData), - ]); + ]).finally(() => { + this._isPersisting = false; + }); } /** @@ -427,7 +440,9 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend { nextBatch, roomsData, }); // put == UPSERT - return txnAsPromise(txn).then(); + return txnAsPromise(txn).then(() => { + logger.log("Persisted sync data up to", nextBatch); + }); }); } From 7ac1d07cc4d26a299f748dd9919a85b5f8ef11a3 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 21 May 2022 13:15:52 +0100 Subject: [PATCH 2/3] don't underscore-prefix private fields --- src/store/indexeddb-local-backend.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/store/indexeddb-local-backend.ts b/src/store/indexeddb-local-backend.ts index 91d0e6a44bf..08a5260ac86 100644 --- a/src/store/indexeddb-local-backend.ts +++ b/src/store/indexeddb-local-backend.ts @@ -127,8 +127,8 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend { private db: IDBDatabase = null; private disconnected = true; private _isNewlyCreated = false; - private _isPersisting = false; - private _pendingUserPresenceData: UserTuple[] = []; + private isPersisting = false; + private pendingUserPresenceData: UserTuple[] = []; /** * Does the actual reading from and writing to the indexeddb @@ -403,13 +403,13 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend { public async syncToDatabase(userTuples: UserTuple[]): Promise { const syncData = this.syncAccumulator.getJSON(true); - if (this._isPersisting) { + if (this.isPersisting) { logger.warn("Skipping syncToDatabase() as persist already in flight"); - this._pendingUserPresenceData.push(...userTuples); + this.pendingUserPresenceData.push(...userTuples); return; } else { - userTuples.unshift(...this._pendingUserPresenceData); - this._isPersisting = true; + userTuples.unshift(...this.pendingUserPresenceData); + this.isPersisting = true; } await Promise.all([ @@ -417,7 +417,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend { this.persistAccountData(syncData.accountData), this.persistSyncData(syncData.nextBatch, syncData.roomsData), ]).finally(() => { - this._isPersisting = false; + this.isPersisting = false; }); } From c12932b2a60e5f6bae5627ce881942d26f8feabb Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 21 May 2022 14:27:07 +0100 Subject: [PATCH 3/3] switch to imperative try...finally --- src/store/indexeddb-local-backend.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/store/indexeddb-local-backend.ts b/src/store/indexeddb-local-backend.ts index 08a5260ac86..a044a95c48c 100644 --- a/src/store/indexeddb-local-backend.ts +++ b/src/store/indexeddb-local-backend.ts @@ -412,13 +412,15 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend { this.isPersisting = true; } - await Promise.all([ - this.persistUserPresenceEvents(userTuples), - this.persistAccountData(syncData.accountData), - this.persistSyncData(syncData.nextBatch, syncData.roomsData), - ]).finally(() => { + try { + await Promise.all([ + this.persistUserPresenceEvents(userTuples), + this.persistAccountData(syncData.accountData), + this.persistSyncData(syncData.nextBatch, syncData.roomsData), + ]); + } finally { this.isPersisting = false; - }); + } } /**