feat(db): add retry to all database interactions #658 #613 #607 #604 #553 #542 #541 #478 #461 #458 #455 #454 #452 #418

This commit is contained in:
Johannes Millan 2020-11-12 19:00:33 +01:00
parent 35e365c2b8
commit 6a856d4e96
3 changed files with 21 additions and 11 deletions

View file

@ -176,6 +176,7 @@
"tslib": "^2.0.0",
"tslint": "~6.1.2",
"typescript": "~4.0.2",
"utils-decorators": "^1.7.1",
"webdav": "^3.5.0",
"zone.js": "~0.11.1"
}

View file

@ -3,12 +3,13 @@ import { DBSchema, IDBPTransaction, openDB } from 'idb';
import { IDBPDatabase } from 'idb/build/esm/entry';
import { BehaviorSubject, Observable } from 'rxjs';
import { filter, shareReplay, take } from 'rxjs/operators';
import { devError } from '../../util/dev-error';
import { retry } from 'utils-decorators';
const DB_NAME = 'SUP';
const DB_MAIN_NAME = 'SUP_STORE';
const VERSION = 2;
const MAX_RETRY_COUNT = 3;
const RETRY_DELAY = 30;
interface MyDb extends DBSchema {
[DB_MAIN_NAME]: any;
@ -23,8 +24,6 @@ export class DatabaseService {
db?: IDBPDatabase<MyDb>;
isReady$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
private _retryCount: number = 0;
private _afterReady$: Observable<boolean> = this.isReady$.pipe(
filter(isReady => isReady),
shareReplay(1),
@ -36,30 +35,35 @@ export class DatabaseService {
this._init().then();
}
@retry({retries: MAX_RETRY_COUNT, delay: RETRY_DELAY})
async load(key: string): Promise<unknown> {
this._lastParams = {a: 'load', key};
await this._afterReady();
return await (this.db as IDBPDatabase<MyDb>).get(DB_MAIN_NAME, key);
}
@retry({retries: MAX_RETRY_COUNT, delay: RETRY_DELAY})
async save(key: string, data: unknown): Promise<unknown> {
this._lastParams = {a: 'save', key, data};
await this._afterReady();
return await (this.db as IDBPDatabase<MyDb>).put(DB_MAIN_NAME, data, key);
}
@retry({retries: MAX_RETRY_COUNT, delay: RETRY_DELAY})
async remove(key: string): Promise<unknown> {
this._lastParams = {a: 'remove', key};
await this._afterReady();
return await (this.db as IDBPDatabase<MyDb>).delete(DB_MAIN_NAME, key);
}
@retry({retries: MAX_RETRY_COUNT, delay: RETRY_DELAY})
async clearDatabase(): Promise<unknown> {
this._lastParams = {a: 'clearDatabase'};
await this._afterReady();
return await (this.db as IDBPDatabase<MyDb>).clear(DB_MAIN_NAME);
}
@retry({retries: MAX_RETRY_COUNT, delay: RETRY_DELAY})
private async _init(): Promise<IDBPDatabase<MyDb>> {
try {
this.db = await openDB<MyDb>(DB_NAME, VERSION, {
@ -81,14 +85,7 @@ export class DatabaseService {
} catch (e) {
console.error('Database initialization failed');
console.error('_lastParams', this._lastParams);
devError('IndexedDB Error ' + this._retryCount);
if (this._retryCount < MAX_RETRY_COUNT) {
this._retryCount++;
console.error(e);
return this._init();
}
alert('IndexedDB Error');
alert('IndexedDB INIT Error');
throw new Error(e);
}

View file

@ -11953,6 +11953,11 @@ tiny-emitter@^2.0.0:
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
tinyqueue@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/tinyqueue/-/tinyqueue-2.0.3.tgz#64d8492ebf39e7801d7bd34062e29b45b2035f08"
integrity sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==
tmp@0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14"
@ -12473,6 +12478,13 @@ util@^0.11.0:
dependencies:
inherits "2.0.3"
utils-decorators@^1.7.1:
version "1.7.1"
resolved "https://registry.yarnpkg.com/utils-decorators/-/utils-decorators-1.7.1.tgz#fc6b83180151d5afb1ee703cf2d6d0d1066a404f"
integrity sha512-OhWtVM0TUhXzg7l0IZnrTx/zY6ca5CKdE08bnNtlJBeK+Q29OSgbslTaIABJfG4MPYqD69jdedbYic9xP/VYrQ==
dependencies:
tinyqueue "^2.0.3"
utils-merge@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"