From e2008a8588221bf8bec8d37f90b74ad0fd3f2fdb Mon Sep 17 00:00:00 2001 From: Xymorot Date: Tue, 5 Jan 2021 23:16:53 +0100 Subject: [PATCH] feat: add some crude wait time optimization to safe-loading URLs in an URL app window --- .eslintrc.json | 4 +- src/main/modules/app-window/url-app-window.ts | 73 +++++++++++++------ types/milliseconds.d.ts | 7 ++ 3 files changed, 61 insertions(+), 23 deletions(-) create mode 100644 types/milliseconds.d.ts diff --git a/.eslintrc.json b/.eslintrc.json index 14edb20..17088ed 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -15,7 +15,7 @@ }, "rules": { "no-shadow": "error", - "no-magic-numbers": ["error", { "ignore": [-1, 0, 1, 10, 100] }], + "no-magic-numbers": ["error", { "ignore": [-1, 0, 1, 2, 10, 100, 1000] }], "no-param-reassign": "error", "prefer-template": "error", "prefer-arrow-callback": "error", @@ -105,7 +105,7 @@ "@typescript-eslint/no-magic-numbers": [ "error", { - "ignore": [-1, 0, 1], + "ignore": [-1, 0, 1, 2, 10, 100, 1000], "ignoreNumericLiteralTypes": true, "ignoreReadonlyClassProperties": true, "ignoreEnums": true diff --git a/src/main/modules/app-window/url-app-window.ts b/src/main/modules/app-window/url-app-window.ts index aef7aa0..c9206b7 100644 --- a/src/main/modules/app-window/url-app-window.ts +++ b/src/main/modules/app-window/url-app-window.ts @@ -4,17 +4,40 @@ import { ISessionHelper } from '../session/i-session-helper'; import { AppWindow } from './app-window'; import { IUrlAppWindow } from './i-url-app-window'; import { WindowClosedError } from './window-closed-error'; +import Timeout = NodeJS.Timeout; export abstract class UrlAppWindow extends AppWindow implements IUrlAppWindow { protected loadOptions: LoadURLOptions; + /** + * the wait interval after a failed load to try again + */ + private waitInterval: number = Milliseconds.TWO_HUNDRED; + + private loadWaitTime: number = 0; + + private loadWaitTimeStep: number = 10; + + private loadWaitTimeStepResetTimeout: Timeout; + + private loadWaitTimeResetTimeoutTime: number = Milliseconds.ONE_MINUTE; + + /** + * when this promise is resolved a safe load is allowed + * + * it resets which each load to resolve again after a wait time + * + * @see loadWaitTime + */ + private loadWait: Promise = Promise.resolve(); + protected constructor( sessionHelper: ISessionHelper, uri: string, options: BrowserWindowConstructorOptions = {}, loadOptions: LoadURLOptions = {} ) { - const securedOptions: BrowserWindowConstructorOptions = { + super(sessionHelper, uri, { ...options, ...{ webPreferences: { @@ -23,9 +46,9 @@ export abstract class UrlAppWindow extends AppWindow implements IUrlAppWindow { contextIsolation: true, }, }, - }; - super(sessionHelper, uri, securedOptions); + }); this.loadOptions = loadOptions; + this.loadWaitTimeStepResetTimeout = setTimeout(() => {}, 0); } public downloadUrlSafe(url: string, savePath: string, options?: LoadURLOptions): Promise { @@ -56,26 +79,34 @@ export abstract class UrlAppWindow extends AppWindow implements IUrlAppWindow { } public async loadUrlSafe(url: string, options?: LoadURLOptions): Promise { - if (!this._window) { - throw new WindowClosedError(); - } - const waitInterval = 1000; - let failedLoad = true; - do { - await new Promise((resolve) => { - if (!this._window) { - throw new WindowClosedError(); - } - this._window.webContents.once('did-navigate', (event, navigationUrl, httpResponseCode) => { - failedLoad = HttpCode.BAD_REQUEST <= httpResponseCode; - resolve(); + return this.loadWait.then(async () => { + let failedLoad = true; + while (failedLoad) { + await new Promise((resolve) => { + if (!this._window) { + throw new WindowClosedError(); + } + this._window.webContents.once('did-navigate', (event, navigationUrl, httpResponseCode) => { + failedLoad = HttpCode.BAD_REQUEST <= httpResponseCode; + if (HttpCode.TOO_MANY_REQUESTS === httpResponseCode) { + // go slower + this.loadWaitTime += this.loadWaitTimeStep; + // but go faster again after a time + clearTimeout(this.loadWaitTimeStepResetTimeout); + this.loadWaitTimeStepResetTimeout = setTimeout(() => { + this.loadWaitTime = 0; + }, this.loadWaitTimeResetTimeoutTime); + } + resolve(); + }); + void this._window.loadURL(url, options); }); - void this._window.loadURL(url, options); - }); - if (failedLoad) { - await promisify(setTimeout)(waitInterval); + if (failedLoad) { + await promisify(setTimeout)(this.waitInterval); + } } - } while (failedLoad); + this.loadWait = promisify(setTimeout)(this.loadWaitTime); + }); } protected load(window: BrowserWindow): Promise { diff --git a/types/milliseconds.d.ts b/types/milliseconds.d.ts new file mode 100644 index 0000000..794740d --- /dev/null +++ b/types/milliseconds.d.ts @@ -0,0 +1,7 @@ +declare const enum Milliseconds { + TWO_HUNDRED = 200, + + ONE_SECOND = 1000, + + ONE_MINUTE = ONE_SECOND * 60, +}