Skip to content

Commit

Permalink
http: refactor responseKeepAlive()
Browse files Browse the repository at this point in the history
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: #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>
  • Loading branch information
ronag authored and targos committed Sep 20, 2019
1 parent d57d47b commit e75661e
Showing 1 changed file with 36 additions and 36 deletions.
72 changes: 36 additions & 36 deletions lib/_http_client.js
Original file line number Diff line number Diff line change
Expand Up @@ -590,59 +590,59 @@ function parserOnIncomingClient(res, shouldKeepAlive) {
}

// client
function responseKeepAlive(res, req) {
function responseKeepAlive(req) {
const socket = req.socket;

if (!req.shouldKeepAlive) {
if (socket.writable) {
debug('AGENT socket.destroySoon()');
if (typeof socket.destroySoon === 'function')
socket.destroySoon();
else
socket.end();
}
assert(!socket.writable);
} else {
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.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);
}
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 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);

if (!req.shouldKeepAlive) {
const socket = req.socket;
if (socket.writable) {
debug('AGENT socket.destroySoon()');
if (typeof socket.destroySoon === 'function')
socket.destroySoon();
else
socket.end();
}
assert(!socket.writable);
} else if (req.finished) {
// We can assume `req.finished` means all data has been written since:
// - `'responseOnEnd'` means we have been assigned a socket.
// - when we have a socket we write directly to it without buffering.
// - `req.finished` means `end()` has been called and no further data.
// can be written
responseKeepAlive(req);
}
}

function requestOnPrefinish() {
const req = this;
const res = this.res;

if (!req.shouldKeepAlive)
return;

if (req._ended)
responseKeepAlive(res, req);
if (req.shouldKeepAlive && req._ended)
responseKeepAlive(req);
}

function emitFreeNT(socket) {
Expand Down

0 comments on commit e75661e

Please sign in to comment.