From b74f08a883ec5c45902d77013cbe924d5b950027 Mon Sep 17 00:00:00 2001 From: ivk Date: Thu, 15 Nov 2018 15:21:12 +0100 Subject: [PATCH] Wait for current transactions to close db. Try to reopen DB. fix #452, fix #708, fix #779 --- src/api/worker/search/DbFacade.js | 40 +++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/api/worker/search/DbFacade.js b/src/api/worker/search/DbFacade.js index 81b1d663eca..0daf4be9c9e 100644 --- a/src/api/worker/search/DbFacade.js +++ b/src/api/worker/search/DbFacade.js @@ -14,8 +14,10 @@ const DB_VERSION = 2 export class DbFacade { _id: string; _db: LazyLoaded; + _activeTransactions: number; constructor(supported: boolean) { + this._activeTransactions = 0 this._db = new LazyLoaded(() => { // If indexedDB is disabled in Firefox, the browser crashes when accessing indexedDB in worker process // ask the main thread if indexedDB is supported. @@ -60,7 +62,10 @@ export class DbFacade { DBOpenRequest.onsuccess = (event) => { //console.log("opened db", event) DBOpenRequest.result.onabort = (event) => console.log("db aborted", event) - DBOpenRequest.result.onclose = (event) => console.log("db closed", event) + DBOpenRequest.result.onclose = (event) => { + console.log("db closed", event) + this._db.reset() + } DBOpenRequest.result.onerror = (event) => console.log("db error", event) callback(null, DBOpenRequest.result) } @@ -92,17 +97,21 @@ export class DbFacade { */ deleteDatabase(): Promise { if (this._db.isLoaded()) { - this._db.getLoaded().close() - return Promise.fromCallback(cb => { - let deleteRequest = indexedDB.deleteDatabase(this._db.getLoaded().name) - deleteRequest.onerror = (event) => { - cb(new DbError(`could not delete database ${this._db.getLoaded().name}`, event)) - } - deleteRequest.onsuccess = (event) => { - this._db.reset() - cb() - } - }) + if (this._activeTransactions > 0) { + return Promise.delay(150).then(() => this.deleteDatabase()) + } else { + this._db.getLoaded().close() + return Promise.fromCallback(cb => { + let deleteRequest = indexedDB.deleteDatabase(this._db.getLoaded().name) + deleteRequest.onerror = (event) => { + cb(new DbError(`could not delete database ${this._db.getLoaded().name}`, event)) + } + deleteRequest.onsuccess = (event) => { + this._db.reset() + cb() + } + }) + } } else { return Promise.resolve() } @@ -114,7 +123,12 @@ export class DbFacade { createTransaction(readOnly: boolean, objectStores: string[]): Promise { return this._db.getAsync().then(db => { try { - return new DbTransaction(db.transaction(objectStores, readOnly ? "readonly" : "readwrite")) + const transaction = new DbTransaction(db.transaction(objectStores, readOnly ? "readonly" : "readwrite")) + this._activeTransactions++ + transaction.wait().finally(() => { + this._activeTransactions-- + }) + return transaction } catch (e) { throw new DbError("could not create transaction", e) }