From 789458e0d40bad168caa8a7c65895b4470dfac45 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 16 May 2023 16:05:55 +0100 Subject: [PATCH] Add methods to terminate idb worker (#3362) --- spec/unit/stores/indexeddb.spec.ts | 27 +++++++++++++++++++++++++++ src/store/index.ts | 5 +++++ src/store/indexeddb-backend.ts | 1 + src/store/indexeddb-local-backend.ts | 7 +++++++ src/store/indexeddb-remote-backend.ts | 7 +++++++ src/store/indexeddb.ts | 7 +++++++ src/store/memory.ts | 4 ++++ src/store/stub.ts | 4 ++++ 8 files changed, 62 insertions(+) diff --git a/spec/unit/stores/indexeddb.spec.ts b/spec/unit/stores/indexeddb.spec.ts index 544a3d75c5b..7f2bc25d458 100644 --- a/spec/unit/stores/indexeddb.spec.ts +++ b/spec/unit/stores/indexeddb.spec.ts @@ -254,4 +254,31 @@ describe("IndexedDBStore", () => { }); await expect(store.startup()).rejects.toThrow("Test"); }); + + it("remote worker should terminate upon destroy call", async () => { + const terminate = jest.fn(); + const worker = new (class MockWorker { + private onmessage!: (data: any) => void; + postMessage(data: any) { + this.onmessage({ + data: { + command: "cmd_success", + seq: data.seq, + result: [], + }, + }); + } + public terminate = terminate; + })() as unknown as Worker; + + const store = new IndexedDBStore({ + indexedDB: indexedDB, + dbName: "database", + localStorage, + workerFactory: () => worker, + }); + await store.startup(); + await expect(store.destroy()).resolves; + expect(terminate).toHaveBeenCalled(); + }); }); diff --git a/src/store/index.ts b/src/store/index.ts index 78741786ac2..ac0a344e852 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -245,4 +245,9 @@ export interface IStore { * Removes a specific batch of to-device messages from the queue */ removeToDeviceBatch(id: number): Promise; + + /** + * Stop the store and perform any appropriate cleanup + */ + destroy(): Promise; } diff --git a/src/store/indexeddb-backend.ts b/src/store/indexeddb-backend.ts index 008867dfc33..c93afb9e705 100644 --- a/src/store/indexeddb-backend.ts +++ b/src/store/indexeddb-backend.ts @@ -35,6 +35,7 @@ export interface IIndexedDBBackend { saveToDeviceBatches(batches: ToDeviceBatchWithTxnId[]): Promise; getOldestToDeviceBatch(): Promise; removeToDeviceBatch(id: number): Promise; + destroy(): Promise; } export type UserTuple = [userId: string, presenceEvent: Partial]; diff --git a/src/store/indexeddb-local-backend.ts b/src/store/indexeddb-local-backend.ts index a82de854e60..3bc5914066a 100644 --- a/src/store/indexeddb-local-backend.ts +++ b/src/store/indexeddb-local-backend.ts @@ -594,4 +594,11 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend { store.delete(id); await txnAsPromise(txn); } + + /* + * Close the database + */ + public async destroy(): Promise { + this.db?.close(); + } } diff --git a/src/store/indexeddb-remote-backend.ts b/src/store/indexeddb-remote-backend.ts index 7e2aa0ccbe9..32ff51efe71 100644 --- a/src/store/indexeddb-remote-backend.ts +++ b/src/store/indexeddb-remote-backend.ts @@ -200,4 +200,11 @@ export class RemoteIndexedDBStoreBackend implements IIndexedDBBackend { logger.warn("Unrecognised message from worker: ", msg); } }; + + /* + * Destroy the web worker + */ + public async destroy(): Promise { + this.worker?.terminate(); + } } diff --git a/src/store/indexeddb.ts b/src/store/indexeddb.ts index cc77bf9c80f..3ca9ea2dca4 100644 --- a/src/store/indexeddb.ts +++ b/src/store/indexeddb.ts @@ -151,6 +151,13 @@ export class IndexedDBStore extends MemoryStore { }); } + /* + * Close the database and destroy any associated workers + */ + public destroy(): Promise { + return this.backend.destroy(); + } + private onClose = (): void => { this.emitter.emit("closed"); }; diff --git a/src/store/memory.ts b/src/store/memory.ts index 091dcd4c8ca..8b560784622 100644 --- a/src/store/memory.ts +++ b/src/store/memory.ts @@ -435,4 +435,8 @@ export class MemoryStore implements IStore { this.pendingToDeviceBatches = this.pendingToDeviceBatches.filter((batch) => batch.id !== id); return Promise.resolve(); } + + public async destroy(): Promise { + // Nothing to do + } } diff --git a/src/store/stub.ts b/src/store/stub.ts index cc128540630..5ea91cf98cc 100644 --- a/src/store/stub.ts +++ b/src/store/stub.ts @@ -266,4 +266,8 @@ export class StubStore implements IStore { public async removeToDeviceBatch(id: number): Promise { return Promise.resolve(); } + + public async destroy(): Promise { + // Nothing to do + } }