http2: cleanup access via Symbols in core

Minimize property access via Symbols by consistently creating
new constants for things that are retrieved multiple times
within a method or a function. Fix cases where existing
constants aren't used where appropriate.

PR-URL: https://github.com/nodejs/node/pull/16327
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
This commit is contained in:
Anatoli Papirovski 2017-10-18 12:02:19 -04:00
parent 58d8fc4c10
commit 023dc4bb83
No known key found for this signature in database
GPG Key ID: 614E2E1ABEB4B2C0

View File

@ -145,8 +145,9 @@ function emit(self, ...args) {
// the block of headers on. // the block of headers on.
function onSessionHeaders(id, cat, flags, headers) { function onSessionHeaders(id, cat, flags, headers) {
const owner = this[kOwner]; const owner = this[kOwner];
const type = owner[kType];
_unrefActive(owner); _unrefActive(owner);
debug(`[${sessionName(owner[kType])}] headers were received on ` + debug(`[${sessionName(type)}] headers were received on ` +
`stream ${id}: ${cat}`); `stream ${id}: ${cat}`);
const streams = owner[kState].streams; const streams = owner[kState].streams;
@ -158,7 +159,7 @@ function onSessionHeaders(id, cat, flags, headers) {
if (stream === undefined) { if (stream === undefined) {
// owner[kType] can be only one of two possible values // owner[kType] can be only one of two possible values
if (owner[kType] === NGHTTP2_SESSION_SERVER) { if (type === NGHTTP2_SESSION_SERVER) {
stream = new ServerHttp2Stream(owner, id, stream = new ServerHttp2Stream(owner, id,
{ readable: !endOfStream }, { readable: !endOfStream },
obj); obj);
@ -193,7 +194,7 @@ function onSessionHeaders(id, cat, flags, headers) {
} else { } else {
event = endOfStream ? 'trailers' : 'headers'; event = endOfStream ? 'trailers' : 'headers';
} }
debug(`[${sessionName(owner[kType])}] emitting stream '${event}' event`); debug(`[${sessionName(type)}] emitting stream '${event}' event`);
process.nextTick(emit, stream, event, obj, flags, headers); process.nextTick(emit, stream, event, obj, flags, headers);
} }
if (endOfStream) { if (endOfStream) {
@ -405,7 +406,6 @@ function requestOnConnect(headers, options) {
const streams = session[kState].streams; const streams = session[kState].streams;
validatePriorityOptions(options); validatePriorityOptions(options);
const handle = session[kHandle];
const headersList = mapToHeaders(headers); const headersList = mapToHeaders(headers);
if (!Array.isArray(headersList)) { if (!Array.isArray(headersList)) {
@ -424,11 +424,11 @@ function requestOnConnect(headers, options) {
// ret will be either the reserved stream ID (if positive) // ret will be either the reserved stream ID (if positive)
// or an error code (if negative) // or an error code (if negative)
const ret = handle.submitRequest(headersList, const ret = session[kHandle].submitRequest(headersList,
streamOptions, streamOptions,
options.parent | 0, options.parent | 0,
options.weight | 0, options.weight | 0,
!!options.exclusive); !!options.exclusive);
// In an error condition, one of three possible response codes will be // In an error condition, one of three possible response codes will be
// possible: // possible:
@ -551,13 +551,13 @@ function setupHandle(session, socket, type, options) {
// Submits a SETTINGS frame to be sent to the remote peer. // Submits a SETTINGS frame to be sent to the remote peer.
function submitSettings(settings) { function submitSettings(settings) {
debug(`[${sessionName(this[kType])}] submitting actual settings`); const type = this[kType];
debug(`[${sessionName(type)}] submitting actual settings`);
_unrefActive(this); _unrefActive(this);
this[kLocalSettings] = undefined; this[kLocalSettings] = undefined;
updateSettingsBuffer(settings); updateSettingsBuffer(settings);
const handle = this[kHandle]; const ret = this[kHandle].submitSettings();
const ret = handle.submitSettings();
let err; let err;
switch (ret) { switch (ret) {
case NGHTTP2_ERR_NOMEM: case NGHTTP2_ERR_NOMEM:
@ -571,24 +571,22 @@ function submitSettings(settings) {
process.nextTick(emit, this, 'error', err); process.nextTick(emit, this, 'error', err);
} }
} }
debug(`[${sessionName(this[kType])}] settings complete`); debug(`[${sessionName(type)}] settings complete`);
} }
// Submits a PRIORITY frame to be sent to the remote peer // Submits a PRIORITY frame to be sent to the remote peer
// Note: If the silent option is true, the change will be made // Note: If the silent option is true, the change will be made
// locally with no PRIORITY frame sent. // locally with no PRIORITY frame sent.
function submitPriority(stream, options) { function submitPriority(stream, options) {
debug(`[${sessionName(this[kType])}] submitting actual priority`); const type = this[kType];
debug(`[${sessionName(type)}] submitting actual priority`);
_unrefActive(this); _unrefActive(this);
const handle = this[kHandle]; const ret = this[kHandle].submitPriority(stream[kID],
const ret = options.parent | 0,
handle.submitPriority( options.weight | 0,
stream[kID], !!options.exclusive,
options.parent | 0, !!options.silent);
options.weight | 0,
!!options.exclusive,
!!options.silent);
let err; let err;
switch (ret) { switch (ret) {
@ -603,17 +601,16 @@ function submitPriority(stream, options) {
process.nextTick(emit, stream, 'error', err); process.nextTick(emit, stream, 'error', err);
} }
} }
debug(`[${sessionName(this[kType])}] priority complete`); debug(`[${sessionName(type)}] priority complete`);
} }
// Submit an RST-STREAM frame to be sent to the remote peer. // Submit an RST-STREAM frame to be sent to the remote peer.
// This will cause the Http2Stream to be closed. // This will cause the Http2Stream to be closed.
function submitRstStream(stream, code) { function submitRstStream(stream, code) {
debug(`[${sessionName(this[kType])}] submit actual rststream`); const type = this[kType];
debug(`[${sessionName(type)}] submit actual rststream`);
_unrefActive(this); _unrefActive(this);
const id = stream[kID]; const ret = this[kHandle].submitRstStream(stream[kID], code);
const handle = this[kHandle];
const ret = handle.submitRstStream(id, code);
let err; let err;
switch (ret) { switch (ret) {
case NGHTTP2_ERR_NOMEM: case NGHTTP2_ERR_NOMEM:
@ -629,7 +626,7 @@ function submitRstStream(stream, code) {
} }
stream.destroy(); stream.destroy();
} }
debug(`[${sessionName(this[kType])}] rststream complete`); debug(`[${sessionName(type)}] rststream complete`);
} }
function doShutdown(self, options) { function doShutdown(self, options) {
@ -654,13 +651,12 @@ function doShutdown(self, options) {
// Submit a graceful or immediate shutdown request for the Http2Session. // Submit a graceful or immediate shutdown request for the Http2Session.
function submitShutdown(options) { function submitShutdown(options) {
debug(`[${sessionName(this[kType])}] submitting actual shutdown request`);
const handle = this[kHandle];
const type = this[kType]; const type = this[kType];
debug(`[${sessionName(type)}] submitting actual shutdown request`);
if (type === NGHTTP2_SESSION_SERVER && if (type === NGHTTP2_SESSION_SERVER &&
options.graceful === true) { options.graceful === true) {
// first send a shutdown notice // first send a shutdown notice
handle.submitShutdownNotice(); this[kHandle].submitShutdownNotice();
// then, on flip of the event loop, do the actual shutdown // then, on flip of the event loop, do the actual shutdown
setImmediate(doShutdown, this, options); setImmediate(doShutdown, this, options);
} else { } else {
@ -827,7 +823,8 @@ class Http2Session extends EventEmitter {
// Submits a SETTINGS frame to be sent to the remote peer. // Submits a SETTINGS frame to be sent to the remote peer.
settings(settings) { settings(settings) {
if (this[kState].destroyed || this[kState].destroying) const state = this[kState];
if (state.destroyed || state.destroying)
throw new errors.Error('ERR_HTTP2_INVALID_SESSION'); throw new errors.Error('ERR_HTTP2_INVALID_SESSION');
// Validate the input first // Validate the input first
@ -855,14 +852,14 @@ class Http2Session extends EventEmitter {
err.actual = settings.enablePush; err.actual = settings.enablePush;
throw err; throw err;
} }
if (this[kState].pendingAck === this[kState].maxPendingAck) { if (state.pendingAck === state.maxPendingAck) {
throw new errors.Error('ERR_HTTP2_MAX_PENDING_SETTINGS_ACK', throw new errors.Error('ERR_HTTP2_MAX_PENDING_SETTINGS_ACK',
this[kState].pendingAck); this[kState].pendingAck);
} }
debug(`[${sessionName(this[kType])}] sending settings`); debug(`[${sessionName(this[kType])}] sending settings`);
this[kState].pendingAck++; state.pendingAck++;
if (this[kState].connecting) { if (state.connecting) {
debug(`[${sessionName(this[kType])}] session still connecting, ` + debug(`[${sessionName(this[kType])}] session still connecting, ` +
'queue settings'); 'queue settings');
this.once('connect', submitSettings.bind(this, settings)); this.once('connect', submitSettings.bind(this, settings));
@ -873,7 +870,8 @@ class Http2Session extends EventEmitter {
// Submits a PRIORITY frame to be sent to the remote peer. // Submits a PRIORITY frame to be sent to the remote peer.
priority(stream, options) { priority(stream, options) {
if (this[kState].destroyed || this[kState].destroying) const state = this[kState];
if (state.destroyed || state.destroying)
throw new errors.Error('ERR_HTTP2_INVALID_SESSION'); throw new errors.Error('ERR_HTTP2_INVALID_SESSION');
if (!(stream instanceof Http2Stream)) { if (!(stream instanceof Http2Stream)) {
@ -885,11 +883,12 @@ class Http2Session extends EventEmitter {
options = Object.assign(Object.create(null), options); options = Object.assign(Object.create(null), options);
validatePriorityOptions(options); validatePriorityOptions(options);
const id = stream[kID];
debug(`[${sessionName(this[kType])}] sending priority for stream ` + debug(`[${sessionName(this[kType])}] sending priority for stream ` +
`${stream[kID]}`); `${id}`);
// A stream cannot be made to depend on itself // A stream cannot be made to depend on itself
if (options.parent === stream[kID]) { if (options.parent === id) {
debug(`[${sessionName(this[kType])}] session still connecting. queue ` + debug(`[${sessionName(this[kType])}] session still connecting. queue ` +
'priority'); 'priority');
throw new errors.TypeError('ERR_INVALID_OPT_VALUE', throw new errors.TypeError('ERR_INVALID_OPT_VALUE',
@ -897,7 +896,7 @@ class Http2Session extends EventEmitter {
options.parent); options.parent);
} }
if (stream[kID] === undefined) { if (id === undefined) {
stream.once('ready', submitPriority.bind(this, stream, options)); stream.once('ready', submitPriority.bind(this, stream, options));
return; return;
} }
@ -924,19 +923,21 @@ class Http2Session extends EventEmitter {
'number'); 'number');
} }
if (this[kState].rst) { const state = stream[kState];
if (state.rst) {
// rst has already been called, do not call again, // rst has already been called, do not call again,
// skip straight to destroy // skip straight to destroy
stream.destroy(); stream.destroy();
return; return;
} }
stream[kState].rst = true; state.rst = true;
stream[kState].rstCode = code; state.rstCode = code;
const id = stream[kID];
debug(`[${sessionName(this[kType])}] initiating rststream for stream ` + debug(`[${sessionName(this[kType])}] initiating rststream for stream ` +
`${stream[kID]}: ${code}`); `${id}: ${code}`);
if (stream[kID] === undefined) { if (id === undefined) {
debug(`[${sessionName(this[kType])}] session still connecting, queue ` + debug(`[${sessionName(this[kType])}] session still connecting, queue ` +
'rststream'); 'rststream');
stream.once('ready', submitRstStream.bind(this, stream, code)); stream.once('ready', submitRstStream.bind(this, stream, code));
@ -976,10 +977,11 @@ class Http2Session extends EventEmitter {
// Graceful or immediate shutdown of the Http2Session. Graceful shutdown // Graceful or immediate shutdown of the Http2Session. Graceful shutdown
// is only supported on the server-side // is only supported on the server-side
shutdown(options, callback) { shutdown(options, callback) {
if (this[kState].destroyed || this[kState].destroying) const state = this[kState];
if (state.destroyed || state.destroying)
throw new errors.Error('ERR_HTTP2_INVALID_SESSION'); throw new errors.Error('ERR_HTTP2_INVALID_SESSION');
if (this[kState].shutdown || this[kState].shuttingDown) if (state.shutdown || state.shuttingDown)
return; return;
const type = this[kType]; const type = this[kType];
@ -1019,21 +1021,21 @@ class Http2Session extends EventEmitter {
options.lastStreamID); options.lastStreamID);
} }
debug(`[${sessionName(this[kType])}] initiating shutdown`); debug(`[${sessionName(type)}] initiating shutdown`);
this[kState].shuttingDown = true; state.shuttingDown = true;
if (callback) { if (callback) {
this.on('shutdown', callback); this.on('shutdown', callback);
} }
if (this[kState].connecting) { if (state.connecting) {
debug(`[${sessionName(this[kType])}] session still connecting, queue ` + debug(`[${sessionName(type)}] session still connecting, queue ` +
'shutdown'); 'shutdown');
this.once('connect', submitShutdown.bind(this, options)); this.once('connect', submitShutdown.bind(this, options));
return; return;
} }
debug(`[${sessionName(this[kType])}] sending shutdown`); debug(`[${sessionName(type)}] sending shutdown`);
submitShutdown.call(this, options); submitShutdown.call(this, options);
} }
@ -1062,7 +1064,8 @@ class ClientHttp2Session extends Http2Session {
// Submits a new HTTP2 request to the connected peer. Returns the // Submits a new HTTP2 request to the connected peer. Returns the
// associated Http2Stream instance. // associated Http2Stream instance.
request(headers, options) { request(headers, options) {
if (this[kState].destroyed || this[kState].destroying) const state = this[kState];
if (state.destroyed || state.destroying)
throw new errors.Error('ERR_HTTP2_INVALID_SESSION'); throw new errors.Error('ERR_HTTP2_INVALID_SESSION');
debug(`[${sessionName(this[kType])}] initiating request`); debug(`[${sessionName(this[kType])}] initiating request`);
_unrefActive(this); _unrefActive(this);
@ -1121,7 +1124,7 @@ class ClientHttp2Session extends Http2Session {
if (options.endStream) if (options.endStream)
stream.end(); stream.end();
if (this[kState].connecting) { if (state.connecting) {
debug(`[${sessionName(this[kType])}] session still connecting, queue ` + debug(`[${sessionName(this[kType])}] session still connecting, queue ` +
'stream init'); 'stream init');
stream.on('connect', onConnect); stream.on('connect', onConnect);
@ -1438,7 +1441,7 @@ class Http2Stream extends Duplex {
debug(`[${sessionName(session[kType])}] sending rstStream for stream ` + debug(`[${sessionName(session[kType])}] sending rstStream for stream ` +
`${this[kID]}: ${code}`); `${this[kID]}: ${code}`);
_unrefActive(this); _unrefActive(this);
this[kSession].rstStream(this, code); session.rstStream(this, code);
} }
rstWithNoError() { rstWithNoError() {
@ -1479,7 +1482,7 @@ class Http2Stream extends Duplex {
debug(`[${sessionName(session[kType])}] sending priority for stream ` + debug(`[${sessionName(session[kType])}] sending priority for stream ` +
`${this[kID]}`); `${this[kID]}`);
_unrefActive(this); _unrefActive(this);
this[kSession].priority(this, options); session.priority(this, options);
} }
// Called by this.destroy(). // Called by this.destroy().
@ -1507,7 +1510,6 @@ class Http2Stream extends Duplex {
function continueStreamDestroy(self, err, callback) { function continueStreamDestroy(self, err, callback) {
const session = self[kSession]; const session = self[kSession];
const handle = session[kHandle];
const state = self[kState]; const state = self[kState];
debug(`[${sessionName(session[kType])}] destroying stream ${self[kID]}`); debug(`[${sessionName(session[kType])}] destroying stream ${self[kID]}`);
@ -1527,7 +1529,7 @@ function continueStreamDestroy(self, err, callback) {
// Unenroll the timer // Unenroll the timer
self.setTimeout(0); self.setTimeout(0);
setImmediate(finishStreamDestroy, self, handle); setImmediate(finishStreamDestroy, self, session[kHandle]);
// RST code 8 not emitted as an error as its used by clients to signify // RST code 8 not emitted as an error as its used by clients to signify
// abort and is already covered by aborted event, also allows more // abort and is already covered by aborted event, also allows more
@ -1579,9 +1581,8 @@ function processRespondWithFD(fd, headers, offset = 0, length = -1,
// Close the writable side of the stream // Close the writable side of the stream
this.end(); this.end();
const handle = session[kHandle]; const ret = session[kHandle].submitFile(this[kID], fd, headers,
const ret = offset, length, streamOptions);
handle.submitFile(this[kID], fd, headers, offset, length, streamOptions);
let err; let err;
switch (ret) { switch (ret) {
case NGHTTP2_ERR_NOMEM: case NGHTTP2_ERR_NOMEM:
@ -1749,9 +1750,8 @@ class ServerHttp2Stream extends Http2Stream {
_unrefActive(this); _unrefActive(this);
const state = session[kState]; const state = session[kState];
const streams = state.streams; const streams = state.streams;
const handle = session[kHandle];
if (!this[kSession].remoteSettings.enablePush) if (!session.remoteSettings.enablePush)
throw new errors.Error('ERR_HTTP2_PUSH_DISABLED'); throw new errors.Error('ERR_HTTP2_PUSH_DISABLED');
if (typeof options === 'function') { if (typeof options === 'function') {
@ -1792,7 +1792,9 @@ class ServerHttp2Stream extends Http2Stream {
const streamOptions = options.endStream ? STREAM_OPTION_EMPTY_PAYLOAD : 0; const streamOptions = options.endStream ? STREAM_OPTION_EMPTY_PAYLOAD : 0;
const ret = handle.submitPushPromise(this[kID], headersList, streamOptions); const ret = session[kHandle].submitPushPromise(this[kID],
headersList,
streamOptions);
let err; let err;
switch (ret) { switch (ret) {
case NGHTTP2_ERR_NOMEM: case NGHTTP2_ERR_NOMEM:
@ -1886,9 +1888,9 @@ class ServerHttp2Stream extends Http2Stream {
if (options.endStream) if (options.endStream)
this.end(); this.end();
const handle = session[kHandle]; const ret = session[kHandle].submitResponse(this[kID],
const ret = headersList,
handle.submitResponse(this[kID], headersList, streamOptions); streamOptions);
let err; let err;
switch (ret) { switch (ret) {
case NGHTTP2_ERR_NOMEM: case NGHTTP2_ERR_NOMEM:
@ -2078,7 +2080,6 @@ class ServerHttp2Stream extends Http2Stream {
} }
_unrefActive(this); _unrefActive(this);
const handle = this[kSession][kHandle];
const headersList = mapToHeaders(headers, const headersList = mapToHeaders(headers,
assertValidPseudoHeaderResponse); assertValidPseudoHeaderResponse);
@ -2086,13 +2087,12 @@ class ServerHttp2Stream extends Http2Stream {
throw headersList; throw headersList;
} }
const ret = const ret = session[kHandle].sendHeaders(this[kID], headersList);
handle.sendHeaders(this[kID], headersList);
let err; let err;
switch (ret) { switch (ret) {
case NGHTTP2_ERR_NOMEM: case NGHTTP2_ERR_NOMEM:
err = new errors.Error('ERR_OUTOFMEMORY'); err = new errors.Error('ERR_OUTOFMEMORY');
process.nextTick(emit, this[kSession], 'error', err); process.nextTick(emit, session, 'error', err);
break; break;
default: default:
if (ret < 0) { if (ret < 0) {
@ -2159,12 +2159,13 @@ Object.defineProperty(Http2Session.prototype, 'setTimeout', setTimeout);
// Set as a replacement for socket.prototype.destroy upon the // Set as a replacement for socket.prototype.destroy upon the
// establishment of a new connection. // establishment of a new connection.
function socketDestroy(error) { function socketDestroy(error) {
const type = this[kSession][kType]; const session = this[kSession];
const type = session[kType];
debug(`[${sessionName(type)}] socket destroy called`); debug(`[${sessionName(type)}] socket destroy called`);
delete this[kServer]; delete this[kServer];
// destroy the session first so that it will stop trying to // destroy the session first so that it will stop trying to
// send data while we close the socket. // send data while we close the socket.
this[kSession].destroy(); session.destroy();
this.destroy = this[kDestroySocket]; this.destroy = this[kDestroySocket];
debug(`[${sessionName(type)}] destroying the socket`); debug(`[${sessionName(type)}] destroying the socket`);
this.destroy(error); this.destroy(error);
@ -2212,12 +2213,13 @@ function sessionOnError(error) {
// When a Socket emits an error, forward it to the session as a // When a Socket emits an error, forward it to the session as a
// socketError; failing that, remove the listener and call destroy // socketError; failing that, remove the listener and call destroy
function socketOnError(error) { function socketOnError(error) {
const type = this[kSession] && this[kSession][kType]; const session = this[kSession];
const type = session && session[kType];
debug(`[${sessionName(type)}] server socket error: ${error.message}`); debug(`[${sessionName(type)}] server socket error: ${error.message}`);
if (kRenegTest.test(error.message)) if (kRenegTest.test(error.message))
return this.destroy(); return this.destroy();
if (this[kSession] !== undefined && if (session !== undefined &&
this[kSession].emit('socketError', error, this)) session.emit('socketError', error, this))
return; return;
this.removeListener('error', socketOnError); this.removeListener('error', socketOnError);
this.destroy(error); this.destroy(error);
@ -2244,8 +2246,9 @@ function sessionOnSocketError(error, socket) {
function sessionOnTimeout() { function sessionOnTimeout() {
debug('session timeout'); debug('session timeout');
process.nextTick(() => { process.nextTick(() => {
const state = this[kState];
// if destroyed or destryoing, do nothing // if destroyed or destryoing, do nothing
if (this[kState].destroyed || this[kState].destroying) if (state.destroyed || state.destroying)
return; return;
const server = this[kServer]; const server = this[kServer];
const socket = this[kSocket]; const socket = this[kSocket];