http: refactor responseKeepAlive()
This tries to simplify the code and make it easier to understand. Took me a while to get my head around the previous implementation. Also minor perf improvement. PR-URL: https://github.com/nodejs/node/pull/28700 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
ed0e5c8c74
commit
627bb6bf87
@ -594,10 +594,36 @@ function parserOnIncomingClient(res, shouldKeepAlive) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// client
|
// client
|
||||||
function responseKeepAlive(res, req) {
|
function responseKeepAlive(req) {
|
||||||
const socket = req.socket;
|
const socket = req.socket;
|
||||||
|
|
||||||
|
debug('AGENT socket keep-alive');
|
||||||
|
if (req.timeoutCb) {
|
||||||
|
socket.setTimeout(0, req.timeoutCb);
|
||||||
|
req.timeoutCb = null;
|
||||||
|
}
|
||||||
|
socket.removeListener('close', socketCloseListener);
|
||||||
|
socket.removeListener('error', socketErrorListener);
|
||||||
|
socket.once('error', freeSocketErrorListener);
|
||||||
|
// There are cases where _handle === null. Avoid those. Passing null to
|
||||||
|
// nextTick() will call getDefaultTriggerAsyncId() to retrieve the id.
|
||||||
|
const asyncId = socket._handle ? socket._handle.getAsyncId() : undefined;
|
||||||
|
// Mark this socket as available, AFTER user-added end
|
||||||
|
// handlers have a chance to run.
|
||||||
|
defaultTriggerAsyncIdScope(asyncId, process.nextTick, emitFreeNT, socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
function responseOnEnd() {
|
||||||
|
const req = this.req;
|
||||||
|
|
||||||
|
if (req.socket && req.timeoutCb) {
|
||||||
|
req.socket.removeListener('timeout', emitRequestTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
req._ended = true;
|
||||||
|
|
||||||
if (!req.shouldKeepAlive) {
|
if (!req.shouldKeepAlive) {
|
||||||
|
const socket = req.socket;
|
||||||
if (socket.writable) {
|
if (socket.writable) {
|
||||||
debug('AGENT socket.destroySoon()');
|
debug('AGENT socket.destroySoon()');
|
||||||
if (typeof socket.destroySoon === 'function')
|
if (typeof socket.destroySoon === 'function')
|
||||||
@ -606,47 +632,21 @@ function responseKeepAlive(res, req) {
|
|||||||
socket.end();
|
socket.end();
|
||||||
}
|
}
|
||||||
assert(!socket.writable);
|
assert(!socket.writable);
|
||||||
} else {
|
} else if (req.finished) {
|
||||||
debug('AGENT socket keep-alive');
|
// We can assume `req.finished` means all data has been written since:
|
||||||
if (req.timeoutCb) {
|
// - `'responseOnEnd'` means we have been assigned a socket.
|
||||||
socket.setTimeout(0, req.timeoutCb);
|
// - when we have a socket we write directly to it without buffering.
|
||||||
req.timeoutCb = null;
|
// - `req.finished` means `end()` has been called and no further data.
|
||||||
}
|
// can be written
|
||||||
socket.removeListener('close', socketCloseListener);
|
responseKeepAlive(req);
|
||||||
socket.removeListener('error', socketErrorListener);
|
|
||||||
socket.removeListener('drain', ondrain);
|
|
||||||
socket.once('error', freeSocketErrorListener);
|
|
||||||
// There are cases where _handle === null. Avoid those. Passing null to
|
|
||||||
// nextTick() will call getDefaultTriggerAsyncId() to retrieve the id.
|
|
||||||
const asyncId = socket._handle ? socket._handle.getAsyncId() : undefined;
|
|
||||||
// Mark this socket as available, AFTER user-added end
|
|
||||||
// handlers have a chance to run.
|
|
||||||
defaultTriggerAsyncIdScope(asyncId, process.nextTick, emitFreeNT, socket);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function responseOnEnd() {
|
|
||||||
const res = this;
|
|
||||||
const req = this.req;
|
|
||||||
|
|
||||||
if (req.socket && req.timeoutCb) {
|
|
||||||
req.socket.removeListener('timeout', emitRequestTimeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
req._ended = true;
|
|
||||||
if (!req.shouldKeepAlive || req.finished)
|
|
||||||
responseKeepAlive(res, req);
|
|
||||||
}
|
|
||||||
|
|
||||||
function requestOnPrefinish() {
|
function requestOnPrefinish() {
|
||||||
const req = this;
|
const req = this;
|
||||||
const res = this.res;
|
|
||||||
|
|
||||||
if (!req.shouldKeepAlive)
|
if (req.shouldKeepAlive && req._ended)
|
||||||
return;
|
responseKeepAlive(req);
|
||||||
|
|
||||||
if (req._ended)
|
|
||||||
responseKeepAlive(res, req);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitFreeNT(socket) {
|
function emitFreeNT(socket) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user