Skip to content

Commit

Permalink
http: add highWaterMark opt in http.createServer
Browse files Browse the repository at this point in the history
  • Loading branch information
HinataKah0 committed Apr 5, 2023
1 parent af8ed02 commit 244311b
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 6 deletions.
5 changes: 3 additions & 2 deletions lib/_http_outgoing.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ function isContentDispositionField(s) {
return s.length === 19 && StringPrototypeToLowerCase(s) === 'content-disposition';
}

function OutgoingMessage() {
function OutgoingMessage(options) {
Stream.call(this);

// Queue that holds all currently pending data, until the response will be
Expand Down Expand Up @@ -149,7 +149,7 @@ function OutgoingMessage() {
this._onPendingData = nop;

this[kErrored] = null;
this[kHighWaterMark] = getDefaultHighWaterMark();
this[kHighWaterMark] = options?.highWaterMark ?? getDefaultHighWaterMark();
}
ObjectSetPrototypeOf(OutgoingMessage.prototype, Stream.prototype);
ObjectSetPrototypeOf(OutgoingMessage, Stream);
Expand Down Expand Up @@ -1171,6 +1171,7 @@ function(err, event) {
};

module.exports = {
kHighWaterMark,
kUniqueHeaders,
parseUniqueHeadersOption,
validateHeaderName,
Expand Down
9 changes: 5 additions & 4 deletions lib/_http_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,8 @@ class HTTPServerAsyncResource {
}
}

function ServerResponse(req) {
OutgoingMessage.call(this);
function ServerResponse(req, options) {
OutgoingMessage.call(this, options);

if (req.method === 'HEAD') this._hasBody = false;

Expand Down Expand Up @@ -513,7 +513,8 @@ function Server(options, requestListener) {
this,
{ allowHalfOpen: true, noDelay: options.noDelay ?? true,
keepAlive: options.keepAlive,
keepAliveInitialDelay: options.keepAliveInitialDelay });
keepAliveInitialDelay: options.keepAliveInitialDelay,
highWaterMark: options.highWaterMark });

if (requestListener) {
this.on('request', requestListener);
Expand Down Expand Up @@ -1019,7 +1020,7 @@ function parserOnIncoming(server, socket, state, req, keepAlive) {
}
}

const res = new server[kServerResponse](req);
const res = new server[kServerResponse](req, { highWaterMark: socket.writableHighWaterMark });
res._keepAliveTimeout = server.keepAliveTimeout;
res._maxRequestsPerSocket = server.maxRequestsPerSocket;
res._onPendingData = updateOutgoingData.bind(undefined,
Expand Down
1 change: 1 addition & 0 deletions lib/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ let maxHeaderSize;
* maxHeaderSize?: number;
* requireHostHeader?: boolean;
* joinDuplicateHeaders?: boolean;
* highWaterMark?: number;
* }} [opts]
* @param {Function} [requestListener]
* @returns {Server}
Expand Down
13 changes: 13 additions & 0 deletions lib/net.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ const {
startPerf,
stopPerf,
} = require('internal/perf/observe');
const { getDefaultHighWaterMark } = require('internal/streams/state');

function getFlags(ipv6Only) {
return ipv6Only === true ? TCPConstants.UV_TCP_IPV6ONLY : 0;
Expand Down Expand Up @@ -1644,6 +1645,15 @@ function Server(options, connectionListener) {
options.keepAliveInitialDelay = 0;
}
}
if (typeof options.highWaterMark !== 'undefined') {
validateNumber(
options.highWaterMark, 'options.highWaterMark',
);

if (options.highWaterMark < 0) {
options.highWaterMark = getDefaultHighWaterMark();

This comment has been minimized.

Copy link
@HinataKah0

HinataKah0 Apr 5, 2023

Author Contributor

Initially I thought it is better to be safe since it affects performance.
I feel a bit conflicting about this.

Either:

  1. Setting invalid value will disable backpressure or
  2. Setting invalid value will fallback to default highWaterMark

Inputs are welcomed. 😄

}
}

this._connections = 0;

Expand All @@ -1658,6 +1668,7 @@ function Server(options, connectionListener) {
this.noDelay = Boolean(options.noDelay);
this.keepAlive = Boolean(options.keepAlive);
this.keepAliveInitialDelay = ~~(options.keepAliveInitialDelay / 1000);
this.highWaterMark = options.highWaterMark ?? getDefaultHighWaterMark();
}
ObjectSetPrototypeOf(Server.prototype, EventEmitter.prototype);
ObjectSetPrototypeOf(Server, EventEmitter);
Expand Down Expand Up @@ -2039,6 +2050,8 @@ function onconnection(err, clientHandle) {
pauseOnCreate: self.pauseOnConnect,
readable: true,
writable: true,
readableHighWaterMark: self.highWaterMark,
writableHighWaterMark: self.highWaterMark,
});

if (self.noDelay && clientHandle.setNoDelay) {
Expand Down
47 changes: 47 additions & 0 deletions test/parallel/test-http-server-options-highwatermark.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Flags: --expose-internals
'use strict';
const common = require('../common');
const assert = require('assert');
const http = require('http');
const { kHighWaterMark } = require('_http_outgoing');

const { getDefaultHighWaterMark } = require('internal/streams/state');

function listen(server) {
server.listen(0, common.mustCall(() => {
http.get({
port: server.address().port,
}, (res) => {
assert.strictEqual(res.statusCode, 200);
res.resume().on('end', common.mustCall(() => {
server.close();
}));
});
}));
}

{
const server = http.createServer({
highWaterMark: getDefaultHighWaterMark() * 2,
}, common.mustCall((req, res) => {
assert.strictEqual(req._readableState.highWaterMark, getDefaultHighWaterMark() * 2);
assert.strictEqual(res[kHighWaterMark], getDefaultHighWaterMark() * 2);
res.statusCode = 200;
res.end();
}));

listen(server);
}

{
const server = http.createServer(
common.mustCall((req, res) => {
assert.strictEqual(req._readableState.highWaterMark, getDefaultHighWaterMark());
assert.strictEqual(res[kHighWaterMark], getDefaultHighWaterMark());
res.statusCode = 200;
res.end();
})
);

listen(server);
}

0 comments on commit 244311b

Please sign in to comment.