@@ -34,6 +34,7 @@ const EventEmitter = require('events');
3434let debug = require ( 'internal/util/debuglog' ) . debuglog ( 'http' , ( fn ) => {
3535 debug = fn ;
3636} ) ;
37+ const { AsyncResource } = require ( 'async_hooks' ) ;
3738const { async_id_symbol } = require ( 'internal/async_hooks' ) . symbols ;
3839const {
3940 codes : {
@@ -47,6 +48,7 @@ const { validateNumber } = require('internal/validators');
4748
4849const kOnKeylog = Symbol ( 'onkeylog' ) ;
4950const kRequestOptions = Symbol ( 'requestOptions' ) ;
51+ const kRequestAsyncResource = Symbol ( 'requestAsyncResource' ) ;
5052// New Agent code.
5153
5254// The largest departure from the previous implementation is that
@@ -127,7 +129,17 @@ function Agent(options) {
127129 const requests = this . requests [ name ] ;
128130 if ( requests && requests . length ) {
129131 const req = requests . shift ( ) ;
130- setRequestSocket ( this , req , socket ) ;
132+ const reqAsyncRes = req [ kRequestAsyncResource ] ;
133+ if ( reqAsyncRes ) {
134+ // Run request within the original async context.
135+ reqAsyncRes . runInAsyncScope ( ( ) => {
136+ asyncResetHandle ( socket ) ;
137+ setRequestSocket ( this , req , socket ) ;
138+ } ) ;
139+ req [ kRequestAsyncResource ] = null ;
140+ } else {
141+ setRequestSocket ( this , req , socket ) ;
142+ }
131143 if ( requests . length === 0 ) {
132144 delete this . requests [ name ] ;
133145 }
@@ -253,14 +265,7 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */,
253265 const sockLen = freeLen + this . sockets [ name ] . length ;
254266
255267 if ( socket ) {
256- // Guard against an uninitialized or user supplied Socket.
257- const handle = socket . _handle ;
258- if ( handle && typeof handle . asyncReset === 'function' ) {
259- // Assign the handle a new asyncId and run any destroy()/init() hooks.
260- handle . asyncReset ( new ReusedHandle ( handle . getProviderType ( ) , handle ) ) ;
261- socket [ async_id_symbol ] = handle . getAsyncId ( ) ;
262- }
263-
268+ asyncResetHandle ( socket ) ;
264269 this . reuseSocket ( socket , req ) ;
265270 setRequestSocket ( this , req , socket ) ;
266271 this . sockets [ name ] . push ( socket ) ;
@@ -284,6 +289,8 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */,
284289
285290 // Used to create sockets for pending requests from different origin
286291 req [ kRequestOptions ] = options ;
292+ // Used to capture the original async context.
293+ req [ kRequestAsyncResource ] = new AsyncResource ( 'QueuedRequest' ) ;
287294
288295 this . requests [ name ] . push ( req ) ;
289296 }
@@ -493,6 +500,16 @@ function setRequestSocket(agent, req, socket) {
493500 socket . setTimeout ( req . timeout ) ;
494501}
495502
503+ function asyncResetHandle ( socket ) {
504+ // Guard against an uninitialized or user supplied Socket.
505+ const handle = socket . _handle ;
506+ if ( handle && typeof handle . asyncReset === 'function' ) {
507+ // Assign the handle a new asyncId and run any destroy()/init() hooks.
508+ handle . asyncReset ( new ReusedHandle ( handle . getProviderType ( ) , handle ) ) ;
509+ socket [ async_id_symbol ] = handle . getAsyncId ( ) ;
510+ }
511+ }
512+
496513module . exports = {
497514 Agent,
498515 globalAgent : new Agent ( )
0 commit comments