◐ Shell
clean mode source ↗

stream: use new AsyncResource instead of bind · nodejs/node@213188e

Original file line numberDiff line numberDiff line change

@@ -45,7 +45,7 @@ const {

4545

} = require('internal/streams/utils');

4646
4747

// Lazy load

48-

let AsyncLocalStorage;

48+

let AsyncResource;

4949

let addAbortListener;

5050
5151

function isRequest(stream) {

@@ -54,6 +54,14 @@ function isRequest(stream) {

5454
5555

const nop = () => {};

5656
57+

function bindAsyncResource(fn, type) {

58+

AsyncResource ??= require('async_hooks').AsyncResource;

59+

const resource = new AsyncResource(type);

60+

return function(...args) {

61+

return resource.runInAsyncScope(fn, this, ...args);

62+

};

63+

}

64+
5765

function eos(stream, options, callback) {

5866

if (arguments.length === 2) {

5967

callback = options;

@@ -66,8 +74,9 @@ function eos(stream, options, callback) {

6674

validateFunction(callback, 'callback');

6775

validateAbortSignal(options.signal, 'options.signal');

6876
69-

AsyncLocalStorage ??= require('async_hooks').AsyncLocalStorage;

70-

callback = once(AsyncLocalStorage.bind(callback));

77+

// Avoid AsyncResource.bind() because it calls ObjectDefineProperties which

78+

// is a bottleneck here.

79+

callback = once(bindAsyncResource(callback, 'STREAM_END_OF_STREAM'));

7180
7281

if (isReadableStream(stream) || isWritableStream(stream)) {

7382

return eosWeb(stream, options, callback);