diff options
author | Andrey Pechkurov <apechkurov@gmail.com> | 2020-07-20 16:05:33 +0300 |
---|---|---|
committer | Andrey Pechkurov <apechkurov@gmail.com> | 2020-07-30 19:26:44 +0300 |
commit | 019ea073babe6db0cf19ffc68e908de5252a1bc8 (patch) | |
tree | 3e7eaab17b87f670c01d54f84a192ea285578fc5 /lib/_http_agent.js | |
parent | 4692e284e305e3ec2418f7f5005bed8d3e62ad11 (diff) | |
download | node-new-019ea073babe6db0cf19ffc68e908de5252a1bc8.tar.gz |
async_hooks: don't reuse resource in HttpAgent when queued
PR-URL: https://github.com/nodejs/node/pull/34439
Fixes: https://github.com/nodejs/node/issues/34401
Refs: https://github.com/nodejs/node/pull/27581
Reviewed-By: Vladimir de Turckheim <vlad2t@hotmail.com>
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
Diffstat (limited to 'lib/_http_agent.js')
-rw-r--r-- | lib/_http_agent.js | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/lib/_http_agent.js b/lib/_http_agent.js index 2d52ea3143..c4430e86ec 100644 --- a/lib/_http_agent.js +++ b/lib/_http_agent.js @@ -34,6 +34,7 @@ const EventEmitter = require('events'); let debug = require('internal/util/debuglog').debuglog('http', (fn) => { debug = fn; }); +const { AsyncResource } = require('async_hooks'); const { async_id_symbol } = require('internal/async_hooks').symbols; const { codes: { @@ -47,6 +48,7 @@ const { validateNumber } = require('internal/validators'); const kOnKeylog = Symbol('onkeylog'); const kRequestOptions = Symbol('requestOptions'); +const kRequestAsyncResource = Symbol('requestAsyncResource'); // New Agent code. // The largest departure from the previous implementation is that @@ -127,7 +129,17 @@ function Agent(options) { const requests = this.requests[name]; if (requests && requests.length) { const req = requests.shift(); - setRequestSocket(this, req, socket); + const reqAsyncRes = req[kRequestAsyncResource]; + if (reqAsyncRes) { + // Run request within the original async context. + reqAsyncRes.runInAsyncScope(() => { + asyncResetHandle(socket); + setRequestSocket(this, req, socket); + }); + req[kRequestAsyncResource] = null; + } else { + setRequestSocket(this, req, socket); + } if (requests.length === 0) { delete this.requests[name]; } @@ -253,14 +265,7 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */, const sockLen = freeLen + this.sockets[name].length; if (socket) { - // Guard against an uninitialized or user supplied Socket. - const handle = socket._handle; - if (handle && typeof handle.asyncReset === 'function') { - // Assign the handle a new asyncId and run any destroy()/init() hooks. - handle.asyncReset(new ReusedHandle(handle.getProviderType(), handle)); - socket[async_id_symbol] = handle.getAsyncId(); - } - + asyncResetHandle(socket); this.reuseSocket(socket, req); setRequestSocket(this, req, socket); this.sockets[name].push(socket); @@ -284,6 +289,8 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */, // Used to create sockets for pending requests from different origin req[kRequestOptions] = options; + // Used to capture the original async context. + req[kRequestAsyncResource] = new AsyncResource('QueuedRequest'); this.requests[name].push(req); } @@ -493,6 +500,16 @@ function setRequestSocket(agent, req, socket) { socket.setTimeout(req.timeout); } +function asyncResetHandle(socket) { + // Guard against an uninitialized or user supplied Socket. + const handle = socket._handle; + if (handle && typeof handle.asyncReset === 'function') { + // Assign the handle a new asyncId and run any destroy()/init() hooks. + handle.asyncReset(new ReusedHandle(handle.getProviderType(), handle)); + socket[async_id_symbol] = handle.getAsyncId(); + } +} + module.exports = { Agent, globalAgent: new Agent() |