Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib: improve lazy loading #14167

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions lib/dgram.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
const assert = require('assert');
const errors = require('internal/errors');
const Buffer = require('buffer').Buffer;
const dns = require('dns');
const util = require('util');
const EventEmitter = require('events');
const setInitTriggerId = require('async_hooks').setInitTriggerId;
Expand All @@ -39,17 +40,13 @@ const BIND_STATE_UNBOUND = 0;
const BIND_STATE_BINDING = 1;
const BIND_STATE_BOUND = 2;

// lazily loaded
// Lazily loaded
var cluster = null;
var dns = null;

const errnoException = util._errnoException;
const exceptionWithHostPort = util._exceptionWithHostPort;

function lookup(address, family, callback) {
if (!dns)
dns = require('dns');

return dns.lookup(address, family, callback);
}

Expand Down
44 changes: 15 additions & 29 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,9 @@
const kCode = Symbol('code');
const messages = new Map();

var util;
function lazyUtil() {
if (!util)
util = require('util');
return util;
}

var assert;
function lazyAssert() {
if (!assert)
assert = require('assert');
return assert;
}
// Lazily loaded
var assert = null;
var util = null;

function makeNodeError(Base) {
return class NodeError extends Base {
Expand All @@ -45,13 +35,14 @@ class AssertionError extends Error {
if (typeof options !== 'object' || options === null) {
throw new exports.TypeError('ERR_INVALID_ARG_TYPE', 'options', 'object');
}
const util = lazyUtil();
const message = options.message ||
`${util.inspect(options.actual).slice(0, 128)} ` +
`${options.operator} ` +
util.inspect(options.expected).slice(0, 128);
if (options.message) {
super(options.message);
} else {
if (util === null) util = require('util');
super(`${util.inspect(options.actual).slice(0, 128)} ` +
`${options.operator} ${util.inspect(options.expected).slice(0, 128)}`);
}

super(message);
this.generatedMessage = !options.message;
this.name = 'AssertionError [ERR_ASSERTION]';
this.code = 'ERR_ASSERTION';
Expand All @@ -63,15 +54,16 @@ class AssertionError extends Error {
}

function message(key, args) {
const assert = lazyAssert();
if (assert === null) assert = require('assert');
assert.strictEqual(typeof key, 'string');
const util = lazyUtil();
const msg = messages.get(key);
assert(msg, `An invalid error message key was used: ${key}.`);
let fmt = util.format;
let fmt;
if (typeof msg === 'function') {
fmt = msg;
} else {
if (util === null) util = require('util');
fmt = util.format;
if (args === undefined || args.length === 0)
return msg;
args.unshift(msg);
Expand Down Expand Up @@ -122,7 +114,6 @@ E('ERR_INDEX_OUT_OF_RANGE', 'Index out of range');
E('ERR_INVALID_ARG_TYPE', invalidArgType);
E('ERR_INVALID_ARRAY_LENGTH',
(name, length, actual) => {
const assert = lazyAssert();
assert.strictEqual(typeof actual, 'number');
return `The "${name}" array must have a length of ${
length}. Received length ${actual}`;
Expand All @@ -148,10 +139,7 @@ E('ERR_INVALID_THIS', 'Value of "this" must be of type %s');
E('ERR_INVALID_TUPLE', '%s must be an iterable %s tuple');
E('ERR_INVALID_URL', 'Invalid URL: %s');
E('ERR_INVALID_URL_SCHEME',
(expected) => {
lazyAssert();
return `The URL must be ${oneOf(expected, 'scheme')}`;
});
(expected) => `The URL must be ${oneOf(expected, 'scheme')}`);
E('ERR_IPC_CHANNEL_CLOSED', 'Channel closed');
E('ERR_IPC_DISCONNECTED', 'IPC channel is already disconnected');
E('ERR_IPC_ONE_PIPE', 'Child process can have only one IPC pipe');
Expand Down Expand Up @@ -181,7 +169,6 @@ E('ERR_V8BREAKITERATOR', 'Full ICU data not installed. ' +
// Add new errors from here...

function invalidArgType(name, expected, actual) {
const assert = lazyAssert();
assert(name, 'name is required');
const type = name.includes('.') ? 'property' : 'argument';
var msg = `The "${name}" ${type} must be ${oneOf(expected, 'type')}`;
Expand All @@ -192,7 +179,6 @@ function invalidArgType(name, expected, actual) {
}

function missingArgs(...args) {
const assert = lazyAssert();
assert(args.length > 0, 'At least one arg needs to be specified');
let msg = 'The ';
const len = args.length;
Expand Down
17 changes: 5 additions & 12 deletions lib/internal/process.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
'use strict';

const errors = require('internal/errors');
var _lazyConstants = null;

function lazyConstants() {
if (!_lazyConstants) {
_lazyConstants = process.binding('constants').os.signals;
}
return _lazyConstants;
}
const constants = process.binding('constants').os.signals;

const assert = process.assert = function(x, msg) {
if (!x) throw new errors.Error('ERR_ASSERTION', msg || 'assertion error');
Expand Down Expand Up @@ -178,8 +171,8 @@ function setupKillAndExit() {
err = process._kill(pid, 0);
} else {
sig = sig || 'SIGTERM';
if (lazyConstants()[sig]) {
err = process._kill(pid, lazyConstants()[sig]);
if (constants[sig]) {
err = process._kill(pid, constants[sig]);
} else {
throw new errors.TypeError('ERR_UNKNOWN_SIGNAL', sig);
}
Expand All @@ -201,7 +194,7 @@ function setupSignalHandlers() {
const signalWraps = {};

function isSignal(event) {
return typeof event === 'string' && lazyConstants()[event] !== undefined;
return typeof event === 'string' && constants[event] !== undefined;
}

// Detect presence of a listener for the special signal types
Expand All @@ -215,7 +208,7 @@ function setupSignalHandlers() {

wrap.onsignal = function() { process.emit(type); };

const signum = lazyConstants()[type];
const signum = constants[type];
const err = wrap.start(signum);
if (err) {
wrap.close();
Expand Down
18 changes: 4 additions & 14 deletions lib/internal/process/stdio.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
'use strict';

exports.setup = setupStdio;

var errors;
const errors = require('internal/errors');

function lazyErrors() {
if (!errors)
errors = require('internal/errors');
return errors;
}
exports.setup = setupStdio;

function setupStdio() {
var stdin;
Expand All @@ -20,8 +14,7 @@ function setupStdio() {
stdout = createWritableStdioStream(1);
stdout.destroySoon = stdout.destroy;
stdout._destroy = function(er, cb) {
// avoid errors if we already emitted
const errors = lazyErrors();
// Avoid errors if we already emitted
er = er || new errors.Error('ERR_STDOUT_CLOSE');
cb(er);
};
Expand All @@ -36,8 +29,7 @@ function setupStdio() {
stderr = createWritableStdioStream(2);
stderr.destroySoon = stderr.destroy;
stderr._destroy = function(er, cb) {
// avoid errors if we already emitted
const errors = lazyErrors();
// Avoid errors if we already emitted
er = er || new errors.Error('ERR_STDERR_CLOSE');
cb(er);
};
Expand Down Expand Up @@ -95,7 +87,6 @@ function setupStdio() {

default:
// Probably an error on in uv_guess_handle()
const errors = lazyErrors();
throw new errors.Error('ERR_UNKNOWN_STDIN_TYPE');
}

Expand Down Expand Up @@ -180,7 +171,6 @@ function createWritableStdioStream(fd) {

default:
// Probably an error on in uv_guess_handle()
const errors = lazyErrors();
throw new errors.Error('ERR_UNKNOWN_STREAM_TYPE');
}

Expand Down
26 changes: 9 additions & 17 deletions lib/internal/process/warning.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,16 @@

const config = process.binding('config');
const prefix = `(${process.release.name}:${process.pid}) `;
const errors = require('internal/errors');

exports.setup = setupProcessWarnings;

var errors;
var fs;
var cachedFd;
var acquiringFd = false;
function nop() {}

function lazyErrors() {
if (!errors)
errors = require('internal/errors');
return errors;
}

function lazyFs() {
if (!fs)
fs = require('fs');
return fs;
}
// Lazily loaded
var fs = null;

function writeOut(message) {
if (console && typeof console.error === 'function')
Expand All @@ -31,7 +21,8 @@ function writeOut(message) {

function onClose(fd) {
return function() {
lazyFs().close(fd, nop);
if (fs === null) fs = require('fs');
fs.close(fd, nop);
};
}

Expand All @@ -53,14 +44,16 @@ function onAcquired(message) {
return function(err, fd) {
if (err)
return writeOut(message);
lazyFs().appendFile(fd, `${message}\n`, nop);
if (fs === null) fs = require('fs');
fs.appendFile(fd, `${message}\n`, nop);
};
}

function acquireFd(cb) {
if (cachedFd === undefined && !acquiringFd) {
acquiringFd = true;
lazyFs().open(config.warningFile, 'a', onOpen(cb));
if (fs === null) fs = require('fs');
fs.open(config.warningFile, 'a', onOpen(cb));
} else if (cachedFd !== undefined && !acquiringFd) {
cb(null, cachedFd);
} else {
Expand Down Expand Up @@ -112,7 +105,6 @@ function setupProcessWarnings() {
// process.emitWarning(str[, type[, code]][, ctor])
// process.emitWarning(str[, options])
process.emitWarning = function(warning, type, code, ctor, now) {
const errors = lazyErrors();
var detail;
if (type !== null && typeof type === 'object' && !Array.isArray(type)) {
ctor = type.ctor;
Expand Down
17 changes: 5 additions & 12 deletions lib/net.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,11 @@ const async_id_symbol = process.binding('async_wrap').async_id_symbol;
const { newUid, setInitTriggerId } = require('async_hooks');
const nextTick = require('internal/process/next_tick').nextTick;
const errors = require('internal/errors');
const dns = require('dns');

var cluster;
var dns;
// `cluster` is only used by `listenInCluster` so for startup performance
// reasons it's lazy loaded.
var cluster = null;

const errnoException = util._errnoException;
const exceptionWithHostPort = util._exceptionWithHostPort;
Expand Down Expand Up @@ -999,7 +1001,6 @@ Socket.prototype.connect = function() {


function lookupAndConnect(self, options) {
const dns = lazyDns();
var host = options.host || 'localhost';
var port = options.port;
var localAddress = options.localAddress;
Expand Down Expand Up @@ -1347,18 +1348,11 @@ function emitListeningNT(self) {
}


function lazyDns() {
if (dns === undefined)
dns = require('dns');
return dns;
}


function listenInCluster(server, address, port, addressType,
backlog, fd, exclusive) {
exclusive = !!exclusive;

if (!cluster) cluster = require('cluster');
if (cluster === null) cluster = require('cluster');

if (cluster.isMaster || exclusive) {
// Will create a new handle
Expand Down Expand Up @@ -1484,7 +1478,6 @@ Server.prototype.listen = function() {
};

function lookupAndListen(self, port, address, backlog, exclusive) {
const dns = lazyDns();
dns.lookup(address, function doListen(err, ip, addressType) {
if (err) {
self.emit('error', err);
Expand Down
6 changes: 2 additions & 4 deletions lib/readline.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@

const errors = require('internal/errors');
const { debug, inherits } = require('util');
const Buffer = require('buffer').Buffer;
const { Buffer } = require('buffer');
const EventEmitter = require('events');
const { StringDecoder } = require('string_decoder');
const {
CSI,
emitKeys,
Expand Down Expand Up @@ -59,7 +60,6 @@ const ESCAPE_DECODER = Symbol('escape-decoder');
// GNU readline library - keyseq-timeout is 500ms (default)
const ESCAPE_CODE_TIMEOUT = 500;


function createInterface(input, output, completer, terminal) {
return new Interface(input, output, completer, terminal);
}
Expand Down Expand Up @@ -181,7 +181,6 @@ function Interface(input, output, completer, terminal) {
input.removeListener('data', ondata);
input.removeListener('end', onend);
});
var StringDecoder = require('string_decoder').StringDecoder; // lazy load
this._decoder = new StringDecoder('utf8');

} else {
Expand Down Expand Up @@ -989,7 +988,6 @@ Interface.prototype._ttyWrite = function(s, key) {

function emitKeypressEvents(stream, iface) {
if (stream[KEYPRESS_DECODER]) return;
var StringDecoder = require('string_decoder').StringDecoder; // lazy load
stream[KEYPRESS_DECODER] = new StringDecoder('utf8');

stream[ESCAPE_DECODER] = emitKeys(stream);
Expand Down