Skip to content

Commit

Permalink
lib: improve perf of AbortSignal creation
Browse files Browse the repository at this point in the history
PR-URL: #52408
Reviewed-By: Yagiz Nizipli <yagiz.nizipli@sentry.io>
Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Minwoo Jung <nodecorelab@gmail.com>
Reviewed-By: Matthew Aitken <maitken033380023@gmail.com>
  • Loading branch information
rluvaton authored and nodejs-github-bot committed Apr 10, 2024
1 parent 64b6777 commit 818c10e
Showing 1 changed file with 38 additions and 37 deletions.
75 changes: 38 additions & 37 deletions lib/internal/abort_controller.js
Expand Up @@ -6,7 +6,6 @@
const {
ObjectAssign,
ObjectDefineProperties,
ObjectSetPrototypeOf,
ObjectDefineProperty,
PromiseResolve,
SafeFinalizationRegistry,
Expand Down Expand Up @@ -69,6 +68,8 @@ const {
let _MessageChannel;
let markTransferMode;

const kDontThrowSymbol = Symbol('kDontThrowSymbol');

// Loading the MessageChannel and markTransferable have to be done lazily
// because otherwise we'll end up with a require cycle that ends up with
// an incomplete initialization of abort_controller.
Expand Down Expand Up @@ -137,8 +138,35 @@ function setWeakAbortSignalTimeout(weakRef, delay) {
}

class AbortSignal extends EventTarget {
constructor() {
throw new ERR_ILLEGAL_CONSTRUCTOR();

/**
* @param {symbol | undefined} dontThrowSymbol
* @param {{
* aborted? : boolean,
* reason? : any,
* transferable? : boolean,
* composite? : boolean,
* }} [init]
* @private
*/
constructor(dontThrowSymbol = undefined, init = kEmptyObject) {
if (dontThrowSymbol !== kDontThrowSymbol) {
throw new ERR_ILLEGAL_CONSTRUCTOR();
}
super();

const {
aborted = false,
reason = undefined,
transferable = false,
composite = false,
} = init;
this[kAborted] = aborted;
this[kReason] = reason;
this[kComposite] = composite;
if (transferable) {
lazyMarkTransferMode(this, false, true);
}
}

/**
Expand Down Expand Up @@ -176,7 +204,7 @@ class AbortSignal extends EventTarget {
*/
static abort(
reason = new DOMException('This operation was aborted', 'AbortError')) {
return createAbortSignal({ aborted: true, reason });
return new AbortSignal(kDontThrowSymbol, { aborted: true, reason });
}

/**
Expand All @@ -185,7 +213,7 @@ class AbortSignal extends EventTarget {
*/
static timeout(delay) {
validateUint32(delay, 'delay', false);
const signal = createAbortSignal();
const signal = new AbortSignal(kDontThrowSymbol);
signal[kTimeout] = true;
clearTimeoutRegistry.register(
signal,
Expand All @@ -199,7 +227,7 @@ class AbortSignal extends EventTarget {
*/
static any(signals) {
validateAbortSignalArray(signals, 'signals');
const resultSignal = createAbortSignal({ composite: true });
const resultSignal = new AbortSignal(kDontThrowSymbol, { composite: true });
if (!signals.length) {
return resultSignal;
}
Expand Down Expand Up @@ -319,7 +347,7 @@ class AbortSignal extends EventTarget {
}

function ClonedAbortSignal() {
return createAbortSignal({ transferable: true });
return new AbortSignal(kDontThrowSymbol, { transferable: true });
}
ClonedAbortSignal.prototype[kDeserialize] = () => {};

Expand All @@ -337,33 +365,6 @@ ObjectDefineProperty(AbortSignal.prototype, SymbolToStringTag, {

defineEventHandler(AbortSignal.prototype, 'abort');

/**
* @param {{
* aborted? : boolean,
* reason? : any,
* transferable? : boolean,
* composite? : boolean,
* }} [init]
* @returns {AbortSignal}
*/
function createAbortSignal(init = kEmptyObject) {
const {
aborted = false,
reason = undefined,
transferable = false,
composite = false,
} = init;
const signal = new EventTarget();
ObjectSetPrototypeOf(signal, AbortSignal.prototype);
signal[kAborted] = aborted;
signal[kReason] = reason;
signal[kComposite] = composite;
if (transferable) {
lazyMarkTransferMode(signal, false, true);
}
return signal;
}

function abortSignal(signal, reason) {
if (signal[kAborted]) return;
signal[kAborted] = true;
Expand All @@ -385,15 +386,15 @@ class AbortController {
* @type {AbortSignal}
*/
get signal() {
this.#signal ??= createAbortSignal();
this.#signal ??= new AbortSignal(kDontThrowSymbol);
return this.#signal;
}

/**
* @param {any} [reason]
*/
abort(reason = new DOMException('This operation was aborted', 'AbortError')) {
abortSignal(this.#signal ??= createAbortSignal(), reason);
abortSignal(this.#signal ??= new AbortSignal(kDontThrowSymbol), reason);
}

[customInspectSymbol](depth, options) {
Expand All @@ -404,7 +405,7 @@ class AbortController {

static [kMakeTransferable]() {
const controller = new AbortController();
controller.#signal = createAbortSignal({ transferable: true });
controller.#signal = new AbortSignal(kDontThrowSymbol, { transferable: true });
return controller;
}
}
Expand Down

0 comments on commit 818c10e

Please sign in to comment.