diff --git a/lib/internal/streams/end-of-stream.js b/lib/internal/streams/end-of-stream.js index 0db2d463b4c6d6..850d4314139afd 100644 --- a/lib/internal/streams/end-of-stream.js +++ b/lib/internal/streams/end-of-stream.js @@ -45,7 +45,7 @@ const { } = require('internal/streams/utils'); // Lazy load -let AsyncLocalStorage; +let AsyncResource; let addAbortListener; function isRequest(stream) { @@ -54,6 +54,14 @@ function isRequest(stream) { const nop = () => {}; +function bindAsyncResource(fn, type) { + AsyncResource ??= require('async_hooks').AsyncResource; + const resource = new AsyncResource(type); + return function(...args) { + return resource.runInAsyncScope(fn, this, ...args); + }; +} + function eos(stream, options, callback) { if (arguments.length === 2) { callback = options; @@ -66,8 +74,9 @@ function eos(stream, options, callback) { validateFunction(callback, 'callback'); validateAbortSignal(options.signal, 'options.signal'); - AsyncLocalStorage ??= require('async_hooks').AsyncLocalStorage; - callback = once(AsyncLocalStorage.bind(callback)); + // Avoid AsyncResource.bind() because it calls ObjectDefineProperties which + // is a bottleneck here. + callback = once(bindAsyncResource(callback, 'STREAM_END_OF_STREAM')); if (isReadableStream(stream) || isWritableStream(stream)) { return eosWeb(stream, options, callback);