summaryrefslogtreecommitdiff
path: root/lib/_http_agent.js
diff options
context:
space:
mode:
authorAndrey Pechkurov <apechkurov@gmail.com>2020-07-20 16:05:33 +0300
committerAndrey Pechkurov <apechkurov@gmail.com>2020-07-30 19:26:44 +0300
commit019ea073babe6db0cf19ffc68e908de5252a1bc8 (patch)
tree3e7eaab17b87f670c01d54f84a192ea285578fc5 /lib/_http_agent.js
parent4692e284e305e3ec2418f7f5005bed8d3e62ad11 (diff)
downloadnode-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.js35
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()