Skip to content

Commit

Permalink
fix(operations): do not call require in a hot path
Browse files Browse the repository at this point in the history
  • Loading branch information
kvwalker committed Jan 7, 2019
1 parent 3da2a35 commit ff82ff4
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 12 deletions.
8 changes: 6 additions & 2 deletions lib/operations/collection_ops.js
Expand Up @@ -18,10 +18,14 @@ const handleCallback = require('../utils').handleCallback;
const indexInformationDb = require('./db_ops').indexInformation;
const isObject = require('../utils').isObject;
const Long = require('mongodb-core').BSON.Long;
const makeLazyLoader = require('../utils').makeLazyLoader;
const MongoError = require('mongodb-core').MongoError;
const ReadPreference = require('mongodb-core').ReadPreference;
const toError = require('../utils').toError;

const loadCollection = makeLazyLoader(`${__dirname}/../collection`);
const loadDb = makeLazyLoader(`${__dirname}/../db`);

/**
* Group function helper
* @ignore
Expand Down Expand Up @@ -987,7 +991,7 @@ function mapReduce(coll, map, reduce, options, callback) {
if (result.result != null && typeof result.result === 'object') {
const doc = result.result;
// Return a collection from another db
const Db = require('../db');
let Db = loadDb();
collection = new Db(doc.db, coll.s.db.s.topology, coll.s.db.s.options).collection(
doc.collection
);
Expand Down Expand Up @@ -1204,7 +1208,7 @@ function removeDocuments(coll, selector, options, callback) {
* @param {Collection~collectionResultCallback} [callback] The results callback
*/
function rename(coll, newName, options, callback) {
const Collection = require('../collection');
let Collection = loadCollection();
// Check the collection name
checkCollectionName(newName);
// Build the command
Expand Down
11 changes: 7 additions & 4 deletions lib/operations/cursor_ops.js
Expand Up @@ -3,9 +3,12 @@
const buildCountCommand = require('./collection_ops').buildCountCommand;
const formattedOrderClause = require('../utils').formattedOrderClause;
const handleCallback = require('../utils').handleCallback;
const makeLazyLoader = require('../utils').makeLazyLoader;
const MongoError = require('mongodb-core').MongoError;
const push = Array.prototype.push;

const loadCursor = makeLazyLoader(`${__dirname}/../cursor`);

/**
* Get the count of documents for this cursor.
*
Expand Down Expand Up @@ -74,7 +77,7 @@ function count(cursor, applySkipLimit, opts, callback) {
* @param {Cursor~resultCallback} callback The result callback.
*/
function each(cursor, callback) {
const Cursor = require('../cursor');
let Cursor = loadCursor();

if (!callback) throw MongoError.create({ message: 'callback is mandatory', driver: true });
if (cursor.isNotified()) return;
Expand Down Expand Up @@ -114,7 +117,7 @@ function each(cursor, callback) {
* @param {Cursor~resultCallback} [callback] The result callback.
*/
function hasNext(cursor, callback) {
const Cursor = require('../cursor');
let Cursor = loadCursor();

if (cursor.s.currentDoc) {
return callback(null, true);
Expand Down Expand Up @@ -165,7 +168,7 @@ function next(cursor, callback) {

// Get the next available document from the cursor, returns null if no more documents are available.
function nextObject(cursor, callback) {
const Cursor = require('../cursor');
let Cursor = loadCursor();

if (cursor.s.state === Cursor.CLOSED || (cursor.isDead && cursor.isDead()))
return handleCallback(
Expand Down Expand Up @@ -196,7 +199,7 @@ function nextObject(cursor, callback) {
* @param {Cursor~toArrayResultCallback} [callback] The result callback.
*/
function toArray(cursor, callback) {
const Cursor = require('../cursor');
let Cursor = loadCursor();

const items = [];

Expand Down
12 changes: 8 additions & 4 deletions lib/operations/db_ops.js
Expand Up @@ -6,6 +6,7 @@ const resolveReadPreference = require('../utils').resolveReadPreference;
const crypto = require('crypto');
const debugOptions = require('../utils').debugOptions;
const handleCallback = require('../utils').handleCallback;
const makeLazyLoader = require('../utils').makeLazyLoader;
const MongoError = require('mongodb-core').MongoError;
const parseIndexOptions = require('../utils').parseIndexOptions;
const ReadPreference = require('mongodb-core').ReadPreference;
Expand All @@ -17,6 +18,9 @@ const findOne = require('./collection_ops').findOne;
const remove = require('./collection_ops').remove;
const updateOne = require('./collection_ops').updateOne;

const loadCollection = makeLazyLoader(`${__dirname}/../collection`);
const loadDb = makeLazyLoader(`${__dirname}/../db`);

const debugFields = [
'authSource',
'w',
Expand Down Expand Up @@ -64,7 +68,7 @@ const illegalCommandFields = [
* @param {Db~resultCallback} [callback] The command result callback
*/
function addUser(db, username, password, options, callback) {
const Db = require('../db');
let Db = loadDb();

// Did the user destroy the topology
if (db.serverConfig && db.serverConfig.isDestroyed())
Expand Down Expand Up @@ -132,7 +136,7 @@ function addUser(db, username, password, options, callback) {
* @param {Db~collectionsResultCallback} [callback] The results callback
*/
function collections(db, options, callback) {
const Collection = require('../collection');
let Collection = loadCollection();

options = Object.assign({}, options, { nameOnly: true });
// Let's get the collection names
Expand Down Expand Up @@ -172,7 +176,7 @@ function collections(db, options, callback) {
* @param {Db~collectionResultCallback} [callback] The results callback
*/
function createCollection(db, name, options, callback) {
const Collection = require('../collection');
let Collection = loadCollection();

// Get the write concern options
const finalOptions = applyWriteConcern(Object.assign({}, options), { db }, options);
Expand Down Expand Up @@ -632,7 +636,7 @@ function profilingLevel(db, options, callback) {
* @param {Db~resultCallback} [callback] The command result callback
*/
function removeUser(db, username, options, callback) {
const Db = require('../db');
let Db = loadDb();

// Attempt to execute command
executeAuthRemoveUserCommand(db, username, options, (err, result) => {
Expand Down
5 changes: 4 additions & 1 deletion lib/operations/mongo_client_ops.js
Expand Up @@ -3,6 +3,7 @@
const authenticate = require('../authenticate');
const deprecate = require('util').deprecate;
const Logger = require('mongodb-core').Logger;
const makeLazyLoader = require('../utils').makeLazyLoader;
const MongoError = require('mongodb-core').MongoError;
const Mongos = require('../topologies/mongos');
const parse = require('mongodb-core').parseConnectionString;
Expand All @@ -11,6 +12,8 @@ const ReplSet = require('../topologies/replset');
const Server = require('../topologies/server');
const ServerSessionPool = require('mongodb-core').Sessions.ServerSessionPool;

const loadClient = makeLazyLoader(`${__dirname}/../mongo_client`);

const monitoringEvents = [
'timeout',
'close',
Expand Down Expand Up @@ -127,7 +130,7 @@ function clearAllEvents(topology) {

// Collect all events in order from SDAM
function collectEvents(mongoClient, topology) {
const MongoClient = require('../mongo_client');
let MongoClient = loadClient();
const collectedEvents = [];

if (mongoClient instanceof MongoClient) {
Expand Down
13 changes: 12 additions & 1 deletion lib/utils.js
Expand Up @@ -694,6 +694,16 @@ function deprecateOptions(config, fn) {
return deprecated;
}

function makeLazyLoader(modulePath) {
let mod;
return function lazyLoad() {
if (!mod) {
mod = require(modulePath);
}
return mod;
};
}

module.exports = {
filterOptions,
mergeOptions,
Expand All @@ -719,5 +729,6 @@ module.exports = {
isPromiseLike,
decorateWithCollation,
decorateWithReadConcern,
deprecateOptions
deprecateOptions,
makeLazyLoader
};

0 comments on commit ff82ff4

Please sign in to comment.