Skip to content

Commit

Permalink
http: reduce multiple output arrays into one
Browse files Browse the repository at this point in the history
Now we are using `output`, `outputEncodings` and `outputCallbacks`
to hold pending data. Reducing them into one array `outputData`
can slightly improve performance and reduce some redundant codes.

PR-URL: #26004
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
  • Loading branch information
starkwang authored and targos committed Feb 11, 2019
1 parent 6c6e678 commit 90c9f1d
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 29 deletions.
6 changes: 2 additions & 4 deletions lib/_http_client.js
Original file line number Diff line number Diff line change
Expand Up @@ -376,10 +376,8 @@ function socketCloseListener() {
// Too bad. That output wasn't getting written.
// This is pretty terrible that it doesn't raise an error.
// Fixed better in v0.10
if (req.output)
req.output.length = 0;
if (req.outputEncodings)
req.outputEncodings.length = 0;
if (req.outputData)
req.outputData.length = 0;

if (parser) {
parser.finish();
Expand Down
43 changes: 20 additions & 23 deletions lib/_http_outgoing.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,7 @@ function OutgoingMessage() {

// Queue that holds all currently pending data, until the response will be
// assigned to the socket (until it will its turn in the HTTP pipeline).
this.output = [];
this.outputEncodings = [];
this.outputCallbacks = [];
this.outputData = [];

// `outputSize` is an approximate measure of how much data is queued on this
// response. `_onPendingData` will be invoked to update similar global
Expand Down Expand Up @@ -219,14 +217,18 @@ OutgoingMessage.prototype._send = function _send(data, encoding, callback) {
data = this._header + data;
} else {
var header = this._header;
if (this.output.length === 0) {
this.output = [header];
this.outputEncodings = ['latin1'];
this.outputCallbacks = [null];
if (this.outputData.length === 0) {
this.outputData = [{
data: header,
encoding: 'latin1',
callback: null
}];
} else {
this.output.unshift(header);
this.outputEncodings.unshift('latin1');
this.outputCallbacks.unshift(null);
this.outputData.unshift({
data: header,
encoding: 'latin1',
callback: null
});
}
this.outputSize += header.length;
this._onPendingData(header.length);
Expand All @@ -253,7 +255,7 @@ function _writeRaw(data, encoding, callback) {

if (conn && conn._httpMessage === this && conn.writable && !conn.destroyed) {
// There might be pending data in the this.output buffer.
if (this.output.length) {
if (this.outputData.length) {
this._flushOutput(conn);
} else if (!data.length) {
if (typeof callback === 'function') {
Expand All @@ -272,9 +274,7 @@ function _writeRaw(data, encoding, callback) {
return conn.write(data, encoding, callback);
}
// Buffer, as long as we're not destroyed.
this.output.push(data);
this.outputEncodings.push(encoding);
this.outputCallbacks.push(callback);
this.outputData.push({ data, encoding, callback });
this.outputSize += data.length;
this._onPendingData(data.length);
return false;
Expand Down Expand Up @@ -737,7 +737,7 @@ OutgoingMessage.prototype.end = function end(chunk, encoding, callback) {
// There is the first message on the outgoing queue, and we've sent
// everything to the socket.
debug('outgoing message end.');
if (this.output.length === 0 &&
if (this.outputData.length === 0 &&
this.connection &&
this.connection._httpMessage === this) {
this._finish();
Expand Down Expand Up @@ -792,22 +792,19 @@ OutgoingMessage.prototype._flush = function _flush() {

OutgoingMessage.prototype._flushOutput = function _flushOutput(socket) {
var ret;
var outputLength = this.output.length;
var outputLength = this.outputData.length;
if (outputLength <= 0)
return ret;

var output = this.output;
var outputEncodings = this.outputEncodings;
var outputCallbacks = this.outputCallbacks;
var outputData = this.outputData;
socket.cork();
for (var i = 0; i < outputLength; i++) {
ret = socket.write(output[i], outputEncodings[i], outputCallbacks[i]);
const { data, encoding, callback } = outputData[i];
ret = socket.write(data, encoding, callback);
}
socket.uncork();

this.output = [];
this.outputEncodings = [];
this.outputCallbacks = [];
this.outputData = [];
this._onPendingData(-this.outputSize);
this.outputSize = 0;

Expand Down
3 changes: 1 addition & 2 deletions test/parallel/test-http-destroyed-socket-write2.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ server.listen(0, function() {
}


assert.strictEqual(req.output.length, 0);
assert.strictEqual(req.outputEncodings.length, 0);
assert.strictEqual(req.outputData.length, 0);
server.close();
}));

Expand Down

0 comments on commit 90c9f1d

Please sign in to comment.