chore: consolidate deferred promise (#8863)

* fix: forward timeout waitForFileChooser

* chore: consolidate deferred promise

Co-authored-by: Alex Rudenko <OrKoN@users.noreply.github.com>
This commit is contained in:
jrandolf 2022-08-30 16:24:51 +02:00 committed by GitHub
parent f477b46f21
commit 9f5cb670e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 65 additions and 101 deletions

View File

@ -17,7 +17,7 @@
import {Protocol} from 'devtools-protocol'; import {Protocol} from 'devtools-protocol';
import {assert} from '../util/assert.js'; import {assert} from '../util/assert.js';
import { import {
createDebuggableDeferredPromise, createDeferredPromise,
DeferredPromise, DeferredPromise,
} from '../util/DeferredPromise.js'; } from '../util/DeferredPromise.js';
import {isErrorLike} from '../util/ErrorLike.js'; import {isErrorLike} from '../util/ErrorLike.js';
@ -150,9 +150,9 @@ export class FrameManager extends EventEmitter {
if (!this.#framesPendingTargetInit.has(targetId)) { if (!this.#framesPendingTargetInit.has(targetId)) {
this.#framesPendingTargetInit.set( this.#framesPendingTargetInit.set(
targetId, targetId,
createDebuggableDeferredPromise( createDeferredPromise({
`Waiting for target frame ${targetId} failed` message: `Waiting for target frame ${targetId} failed`,
) })
); );
} }
const result = await Promise.all([ const result = await Promise.all([
@ -318,9 +318,9 @@ export class FrameManager extends EventEmitter {
if (!this.#framesPendingAttachment.has(frameId)) { if (!this.#framesPendingAttachment.has(frameId)) {
this.#framesPendingAttachment.set( this.#framesPendingAttachment.set(
frameId, frameId,
createDebuggableDeferredPromise( createDeferredPromise({
`Waiting for frame ${frameId} to attach failed` message: `Waiting for frame ${frameId} to attach failed`,
) })
); );
} }
frame.then(() => { frame.then(() => {

View File

@ -24,7 +24,7 @@ import {HTTPResponse} from './HTTPResponse.js';
import {FetchRequestId, NetworkEventManager} from './NetworkEventManager.js'; import {FetchRequestId, NetworkEventManager} from './NetworkEventManager.js';
import {debugError, isString} from './util.js'; import {debugError, isString} from './util.js';
import { import {
createDebuggableDeferredPromise, createDeferredPromise,
DeferredPromise, DeferredPromise,
} from '../util/DeferredPromise.js'; } from '../util/DeferredPromise.js';
@ -144,9 +144,9 @@ export class NetworkManager extends EventEmitter {
if (this.#deferredInitPromise) { if (this.#deferredInitPromise) {
return this.#deferredInitPromise; return this.#deferredInitPromise;
} }
this.#deferredInitPromise = createDebuggableDeferredPromise<void>( this.#deferredInitPromise = createDeferredPromise<void>({
'NetworkManager initialization timed out' message: 'NetworkManager initialization timed out',
); });
const init = Promise.all([ const init = Promise.all([
this.#ignoreHTTPSErrors this.#ignoreHTTPSErrors
? this.#client.send('Security.setIgnoreCertificateErrors', { ? this.#client.send('Security.setIgnoreCertificateErrors', {

View File

@ -69,7 +69,7 @@ import {
} from './util.js'; } from './util.js';
import {isErrorLike} from '../util/ErrorLike.js'; import {isErrorLike} from '../util/ErrorLike.js';
import { import {
createDeferredPromiseWithTimer, createDeferredPromise,
DeferredPromise, DeferredPromise,
} from '../util/DeferredPromise.js'; } from '../util/DeferredPromise.js';
import {WebWorker} from './WebWorker.js'; import {WebWorker} from './WebWorker.js';
@ -769,9 +769,10 @@ export class Page extends EventEmitter {
} }
const {timeout = this.#timeoutSettings.timeout()} = options; const {timeout = this.#timeoutSettings.timeout()} = options;
const promise = createDeferredPromiseWithTimer<FileChooser>( const promise = createDeferredPromise<FileChooser>({
`Waiting for \`FileChooser\` failed: ${timeout}ms exceeded` message: `Waiting for \`FileChooser\` failed: ${timeout}ms exceeded`,
); timeout,
});
this.#fileChooserPromises.add(promise); this.#fileChooserPromises.add(promise);
return promise.catch(error => { return promise.catch(error => {
this.#fileChooserPromises.delete(promise); this.#fileChooserPromises.delete(promise);

View File

@ -22,7 +22,7 @@ export const isNode = !!(typeof process !== 'undefined' && process.version);
/** /**
* @internal * @internal
*/ */
export const deferredPromiseDebugTimeout = export const DEFERRED_PROMISE_DEBUG_TIMEOUT =
typeof process !== 'undefined' && typeof process !== 'undefined' &&
typeof process.env['PUPPETEER_DEFERRED_PROMISE_DEBUG_TIMEOUT'] !== 'undefined' typeof process.env['PUPPETEER_DEFERRED_PROMISE_DEBUG_TIMEOUT'] !== 'undefined'
? Number(process.env['PUPPETEER_DEFERRED_PROMISE_DEBUG_TIMEOUT']) ? Number(process.env['PUPPETEER_DEFERRED_PROMISE_DEBUG_TIMEOUT'])

View File

@ -1,5 +1,5 @@
import {TimeoutError} from '../common/Errors.js'; import {TimeoutError} from '../common/Errors.js';
import {deferredPromiseDebugTimeout} from '../environment.js'; import {DEFERRED_PROMISE_DEBUG_TIMEOUT} from '../environment.js';
/** /**
* @internal * @internal
@ -11,18 +11,27 @@ export interface DeferredPromise<T> extends Promise<T> {
reject: (_: Error) => void; reject: (_: Error) => void;
} }
interface DeferredPromiseOptions {
message?: string;
timeout?: number;
isDebug?: boolean;
}
/** /**
* Creates an returns a promise along with the resolve/reject functions. * Creates an returns a promise along with the resolve/reject functions.
* *
* If the promise has not been resolved/rejected withing the `timeout` period, * If the promise has not been resolved/rejected within the `timeout` period,
* the promise gets rejected with a timeout error. * the promise gets rejected with a timeout error.
* *
* @internal * @internal
*/ */
export function createDeferredPromiseWithTimer<T>( export function createDeferredPromise<T>({
timeoutMessage: string, message,
timeout = 5000 timeout = 5000,
): DeferredPromise<T> { }: DeferredPromiseOptions = {}): DeferredPromise<T> {
if (DEFERRED_PROMISE_DEBUG_TIMEOUT > 0 && !timeout) {
timeout = DEFERRED_PROMISE_DEBUG_TIMEOUT;
}
let isResolved = false; let isResolved = false;
let isRejected = false; let isRejected = false;
let resolver = (_: T): void => {}; let resolver = (_: T): void => {};
@ -31,11 +40,10 @@ export function createDeferredPromiseWithTimer<T>(
resolver = resolve; resolver = resolve;
rejector = reject; rejector = reject;
}); });
const timeoutId = const timeoutId = message
timeout > 0
? setTimeout(() => { ? setTimeout(() => {
isRejected = true; isRejected = true;
rejector(new TimeoutError(timeoutMessage)); rejector(new TimeoutError(message));
}, timeout) }, timeout)
: undefined; : undefined;
return Object.assign(taskPromise, { return Object.assign(taskPromise, {
@ -46,7 +54,9 @@ export function createDeferredPromiseWithTimer<T>(
return isResolved || isRejected; return isResolved || isRejected;
}, },
resolve: (value: T) => { resolve: (value: T) => {
if (timeoutId) {
clearTimeout(timeoutId); clearTimeout(timeoutId);
}
isResolved = true; isResolved = true;
resolver(value); resolver(value);
}, },
@ -57,50 +67,3 @@ export function createDeferredPromiseWithTimer<T>(
}, },
}); });
} }
/**
* Creates an returns a promise along with the resolve/reject functions.
*
* @internal
*/
export function createDeferredPromise<T>(): DeferredPromise<T> {
let isResolved = false;
let isRejected = false;
let resolver = (_: T): void => {};
let rejector = (_: Error) => {};
const taskPromise = new Promise<T>((resolve, reject) => {
resolver = resolve;
rejector = reject;
});
return Object.assign(taskPromise, {
resolved: () => {
return isResolved;
},
finished: () => {
return isResolved || isRejected;
},
resolve: (value: T) => {
isResolved = true;
resolver(value);
},
reject: (err: Error) => {
isRejected = true;
rejector(err);
},
});
}
/**
* @internal
*/
export function createDebuggableDeferredPromise<T>(
timeoutMessage: string
): DeferredPromise<T> {
if (deferredPromiseDebugTimeout > 0) {
return createDeferredPromiseWithTimer(
timeoutMessage,
deferredPromiseDebugTimeout
);
}
return createDeferredPromise();
}