@@ -34,6 +34,7 @@ const EventEmitter = require('events');
34
34
let debug = require ( 'internal/util/debuglog' ) . debuglog ( 'http' , ( fn ) => {
35
35
debug = fn ;
36
36
} ) ;
37
+ const { AsyncResource } = require ( 'async_hooks' ) ;
37
38
const { async_id_symbol } = require ( 'internal/async_hooks' ) . symbols ;
38
39
const {
39
40
codes : {
@@ -47,6 +48,7 @@ const { validateNumber } = require('internal/validators');
47
48
48
49
const kOnKeylog = Symbol ( 'onkeylog' ) ;
49
50
const kRequestOptions = Symbol ( 'requestOptions' ) ;
51
+ const kRequestAsyncResource = Symbol ( 'requestAsyncResource' ) ;
50
52
// New Agent code.
51
53
52
54
// The largest departure from the previous implementation is that
@@ -127,7 +129,17 @@ function Agent(options) {
127
129
const requests = this . requests [ name ] ;
128
130
if ( requests && requests . length ) {
129
131
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
+ }
131
143
if ( requests . length === 0 ) {
132
144
delete this . requests [ name ] ;
133
145
}
@@ -253,14 +265,7 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */,
253
265
const sockLen = freeLen + this . sockets [ name ] . length ;
254
266
255
267
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 ) ;
264
269
this . reuseSocket ( socket , req ) ;
265
270
setRequestSocket ( this , req , socket ) ;
266
271
this . sockets [ name ] . push ( socket ) ;
@@ -284,6 +289,8 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */,
284
289
285
290
// Used to create sockets for pending requests from different origin
286
291
req [ kRequestOptions ] = options ;
292
+ // Used to capture the original async context.
293
+ req [ kRequestAsyncResource ] = new AsyncResource ( 'QueuedRequest' ) ;
287
294
288
295
this . requests [ name ] . push ( req ) ;
289
296
}
@@ -493,6 +500,16 @@ function setRequestSocket(agent, req, socket) {
493
500
socket . setTimeout ( req . timeout ) ;
494
501
}
495
502
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
+
496
513
module . exports = {
497
514
Agent,
498
515
globalAgent : new Agent ( )
0 commit comments