feat: add some crude wait time optimization to safe-loading URLs in an URL app window

This commit is contained in:
Xymorot 2021-01-05 23:16:53 +01:00
parent 9c2adbb626
commit e2008a8588
3 changed files with 61 additions and 23 deletions

View File

@ -15,7 +15,7 @@
}, },
"rules": { "rules": {
"no-shadow": "error", "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", "no-param-reassign": "error",
"prefer-template": "error", "prefer-template": "error",
"prefer-arrow-callback": "error", "prefer-arrow-callback": "error",
@ -105,7 +105,7 @@
"@typescript-eslint/no-magic-numbers": [ "@typescript-eslint/no-magic-numbers": [
"error", "error",
{ {
"ignore": [-1, 0, 1], "ignore": [-1, 0, 1, 2, 10, 100, 1000],
"ignoreNumericLiteralTypes": true, "ignoreNumericLiteralTypes": true,
"ignoreReadonlyClassProperties": true, "ignoreReadonlyClassProperties": true,
"ignoreEnums": true "ignoreEnums": true

View File

@ -4,17 +4,40 @@ import { ISessionHelper } from '../session/i-session-helper';
import { AppWindow } from './app-window'; import { AppWindow } from './app-window';
import { IUrlAppWindow } from './i-url-app-window'; import { IUrlAppWindow } from './i-url-app-window';
import { WindowClosedError } from './window-closed-error'; import { WindowClosedError } from './window-closed-error';
import Timeout = NodeJS.Timeout;
export abstract class UrlAppWindow extends AppWindow implements IUrlAppWindow { export abstract class UrlAppWindow extends AppWindow implements IUrlAppWindow {
protected loadOptions: LoadURLOptions; 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<void> = Promise.resolve();
protected constructor( protected constructor(
sessionHelper: ISessionHelper, sessionHelper: ISessionHelper,
uri: string, uri: string,
options: BrowserWindowConstructorOptions = {}, options: BrowserWindowConstructorOptions = {},
loadOptions: LoadURLOptions = {} loadOptions: LoadURLOptions = {}
) { ) {
const securedOptions: BrowserWindowConstructorOptions = { super(sessionHelper, uri, {
...options, ...options,
...{ ...{
webPreferences: { webPreferences: {
@ -23,9 +46,9 @@ export abstract class UrlAppWindow extends AppWindow implements IUrlAppWindow {
contextIsolation: true, contextIsolation: true,
}, },
}, },
}; });
super(sessionHelper, uri, securedOptions);
this.loadOptions = loadOptions; this.loadOptions = loadOptions;
this.loadWaitTimeStepResetTimeout = setTimeout(() => {}, 0);
} }
public downloadUrlSafe(url: string, savePath: string, options?: LoadURLOptions): Promise<void> { public downloadUrlSafe(url: string, savePath: string, options?: LoadURLOptions): Promise<void> {
@ -56,26 +79,34 @@ export abstract class UrlAppWindow extends AppWindow implements IUrlAppWindow {
} }
public async loadUrlSafe(url: string, options?: LoadURLOptions): Promise<void> { public async loadUrlSafe(url: string, options?: LoadURLOptions): Promise<void> {
if (!this._window) { return this.loadWait.then(async () => {
throw new WindowClosedError(); let failedLoad = true;
} while (failedLoad) {
const waitInterval = 1000; await new Promise<void>((resolve) => {
let failedLoad = true; if (!this._window) {
do { throw new WindowClosedError();
await new Promise<void>((resolve) => { }
if (!this._window) { this._window.webContents.once('did-navigate', (event, navigationUrl, httpResponseCode) => {
throw new WindowClosedError(); failedLoad = HttpCode.BAD_REQUEST <= httpResponseCode;
} if (HttpCode.TOO_MANY_REQUESTS === httpResponseCode) {
this._window.webContents.once('did-navigate', (event, navigationUrl, httpResponseCode) => { // go slower
failedLoad = HttpCode.BAD_REQUEST <= httpResponseCode; this.loadWaitTime += this.loadWaitTimeStep;
resolve(); // 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)(this.waitInterval);
if (failedLoad) { }
await promisify(setTimeout)(waitInterval);
} }
} while (failedLoad); this.loadWait = promisify(setTimeout)(this.loadWaitTime);
});
} }
protected load(window: BrowserWindow): Promise<void> { protected load(window: BrowserWindow): Promise<void> {

7
types/milliseconds.d.ts vendored Normal file
View File

@ -0,0 +1,7 @@
declare const enum Milliseconds {
TWO_HUNDRED = 200,
ONE_SECOND = 1000,
ONE_MINUTE = ONE_SECOND * 60,
}