Skip to content

Commit

Permalink
lib: reuse default DOMException in AbortController
Browse files Browse the repository at this point in the history
  • Loading branch information
debadree25 committed May 7, 2023
1 parent 351bf77 commit 832efd8
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
16 changes: 16 additions & 0 deletions benchmark/events/abortcontroller-abort.js
@@ -0,0 +1,16 @@
'use strict';
const common = require('../common.js');

const bench = common.createBenchmark(main, {
n: [1e6],
});

function main({ n }) {
bench.start();
for (let i = 0; i < n; i++) {
const ac = new AbortController();
ac.signal.addEventListener('abort', () => {});
ac.abort();
}
bench.end(n);
}
30 changes: 27 additions & 3 deletions lib/internal/abort_controller.js
Expand Up @@ -30,6 +30,7 @@ const {
customInspectSymbol,
kEmptyObject,
kEnumerableProperty,
SideEffectFreeRegExpPrototypeSymbolReplace,
} = require('internal/util');
const { inspect } = require('internal/util/inspect');
const {
Expand Down Expand Up @@ -63,11 +64,14 @@ const {

let _MessageChannel;
let makeTransferable;
let defaultDOMException;

// Loading the MessageChannel and makeTransferable 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.

const userModuleRegExp = /^ {4}at (?:[^/\\(]+ \()(?!node:(.+):\d+:\d+\)$).*/gm;

function lazyMessageChannel() {
_MessageChannel ??= require('internal/worker/io').MessageChannel;
return new _MessageChannel();
Expand All @@ -79,6 +83,21 @@ function lazyMakeTransferable(obj) {
return makeTransferable(obj);
}

function lazyDOMException() {
if (defaultDOMException) {
return defaultDOMException;
}

defaultDOMException = new DOMException('This operation was aborted', 'AbortError');

// Avoid V8 leak and remove userland stackstrace
defaultDOMException.stack = SideEffectFreeRegExpPrototypeSymbolReplace(
userModuleRegExp,
defaultDOMException.stack,
'');
return defaultDOMException;
}

const clearTimeoutRegistry = new SafeFinalizationRegistry(clearTimeout);
const timeOutSignals = new SafeSet();

Expand Down Expand Up @@ -166,8 +185,10 @@ class AbortSignal extends EventTarget {
* @param {any} [reason]
* @returns {AbortSignal}
*/
static abort(
reason = new DOMException('This operation was aborted', 'AbortError')) {
static abort(reason) {
if (reason === undefined) {
reason = lazyDOMException();
}
return createAbortSignal({ aborted: true, reason });
}

Expand Down Expand Up @@ -328,7 +349,10 @@ class AbortController {
/**
* @param {any} [reason]
*/
abort(reason = new DOMException('This operation was aborted', 'AbortError')) {
abort(reason) {
if (reason === undefined) {
reason = lazyDOMException();
}
abortSignal(this.#signal ??= createAbortSignal(), reason);
}

Expand Down

0 comments on commit 832efd8

Please sign in to comment.