From 1f0c6f3d6010294e3272da232f20ccb756f4204a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 3 Oct 2019 22:26:33 -0400 Subject: [PATCH] refactor: async/await mongo --- src/database/mongo.js | 202 ++++++++++++------------------- src/database/mongo/connection.js | 6 +- 2 files changed, 77 insertions(+), 131 deletions(-) diff --git a/src/database/mongo.js b/src/database/mongo.js index 7fced0fc0e..1f095bd44e 100644 --- a/src/database/mongo.js +++ b/src/database/mongo.js @@ -3,7 +3,6 @@ const winston = require('winston'); -const async = require('async'); const nconf = require('nconf'); const session = require('express-session'); const semver = require('semver'); @@ -61,63 +60,39 @@ mongoModule.questions = [ }, ]; -mongoModule.init = function (callback) { - callback = callback || function () { }; - - connection.connect(nconf.get('mongo'), function (err, _client) { - if (err) { - winston.error('NodeBB could not connect to your Mongo database. Mongo returned the following error', err); - return callback(err); - } - client = _client; - mongoModule.client = client.db(); - callback(); - }); +mongoModule.init = async function () { + client = await connection.connect(nconf.get('mongo')); + mongoModule.client = client.db(); }; -mongoModule.createSessionStore = function (options, callback) { - connection.connect(options, function (err, client) { - if (err) { - return callback(err); - } - const meta = require('../meta'); - const sessionStore = require('connect-mongo')(session); - const store = new sessionStore({ - client: client, - ttl: meta.getSessionTTLSeconds(), - }); - - callback(null, store); +mongoModule.createSessionStore = async function (options) { + const client = await connection.connect(options); + const meta = require('../meta'); + const sessionStore = require('connect-mongo')(session); + const store = new sessionStore({ + client: client, + ttl: meta.getSessionTTLSeconds(), }); -}; -mongoModule.createIndices = function (callback) { - function createIndex(collection, index, options, callback) { - mongoModule.client.collection(collection).createIndex(index, options, callback); - } + return store; +}; +mongoModule.createIndices = async function () { if (!mongoModule.client) { winston.warn('[database/createIndices] database not initialized'); - return callback(); + return; } winston.info('[database] Checking database indices.'); - async.series([ - async.apply(createIndex, 'objects', { _key: 1, score: -1 }, { background: true }), - async.apply(createIndex, 'objects', { _key: 1, value: -1 }, { background: true, unique: true, sparse: true }), - async.apply(createIndex, 'objects', { expireAt: 1 }, { expireAfterSeconds: 0, background: true }), - ], function (err) { - if (err) { - winston.error('Error creating index', err); - return callback(err); - } - winston.info('[database] Checking database indices done!'); - callback(); - }); + const collection = mongoModule.client.collection('objects'); + await collection.createIndex({ _key: 1, score: -1 }, { background: true }); + await collection.createIndex({ _key: 1, value: -1 }, { background: true, unique: true, sparse: true }); + await collection.createIndex({ expireAt: 1 }, { expireAfterSeconds: 0, background: true }); + winston.info('[database] Checking database indices done!'); }; mongoModule.checkCompatibility = function (callback) { - var mongoPkg = require('mongodb/package.json'); + const mongoPkg = require('mongodb/package.json'); mongoModule.checkCompatibilityVersion(mongoPkg.version, callback); }; @@ -129,97 +104,70 @@ mongoModule.checkCompatibilityVersion = function (version, callback) { callback(); }; -mongoModule.info = function (db, callback) { - async.waterfall([ - function (next) { - if (db) { - return setImmediate(next, null, db); - } - connection.connect(nconf.get('mongo'), function (err, client) { - next(err, client ? client.db() : undefined); - }); - }, - function (db, next) { - mongoModule.client = mongoModule.client || db; - - async.parallel({ - serverStatus: function (next) { - db.command({ serverStatus: 1 }, next); - }, - stats: function (next) { - db.command({ dbStats: 1 }, next); - }, - listCollections: function (next) { - getCollectionStats(db, next); - }, - }, next); - }, - function (results, next) { - var stats = results.stats || {}; - results.serverStatus = results.serverStatus || {}; - var scale = 1024 * 1024 * 1024; - - results.listCollections = results.listCollections.map(function (collectionInfo) { - return { - name: collectionInfo.ns, - count: collectionInfo.count, - size: collectionInfo.size, - avgObjSize: collectionInfo.avgObjSize, - storageSize: collectionInfo.storageSize, - totalIndexSize: collectionInfo.totalIndexSize, - indexSizes: collectionInfo.indexSizes, - }; - }); - - stats.mem = results.serverStatus.mem || {}; - stats.mem.resident = (stats.mem.resident / 1024).toFixed(3); - stats.mem.virtual = (stats.mem.virtual / 1024).toFixed(3); - stats.mem.mapped = (stats.mem.mapped / 1024).toFixed(3); - stats.collectionData = results.listCollections; - stats.network = results.serverStatus.network || {}; - stats.network.bytesIn = (stats.network.bytesIn / scale).toFixed(3); - stats.network.bytesOut = (stats.network.bytesOut / scale).toFixed(3); - stats.network.numRequests = utils.addCommas(stats.network.numRequests); - stats.raw = JSON.stringify(stats, null, 4); - - stats.avgObjSize = stats.avgObjSize.toFixed(2); - stats.dataSize = (stats.dataSize / scale).toFixed(3); - stats.storageSize = (stats.storageSize / scale).toFixed(3); - stats.fileSize = stats.fileSize ? (stats.fileSize / scale).toFixed(3) : 0; - stats.indexSize = (stats.indexSize / scale).toFixed(3); - stats.storageEngine = results.serverStatus.storageEngine ? results.serverStatus.storageEngine.name : 'mmapv1'; - stats.host = results.serverStatus.host; - stats.version = results.serverStatus.version; - stats.uptime = results.serverStatus.uptime; - stats.mongo = true; - - next(null, stats); - }, - ], callback); +mongoModule.info = async function (db) { + if (!db) { + const client = await connection.connect(nconf.get('mongo')); + db = client.db(); + } + mongoModule.client = mongoModule.client || db; + + let [serverStatus, stats, listCollections] = await Promise.all([ + db.command({ serverStatus: 1 }), + db.command({ dbStats: 1 }), + getCollectionStats(db), + ]); + stats = stats || {}; + serverStatus = serverStatus || {}; + const scale = 1024 * 1024 * 1024; + + listCollections = listCollections.map(function (collectionInfo) { + return { + name: collectionInfo.ns, + count: collectionInfo.count, + size: collectionInfo.size, + avgObjSize: collectionInfo.avgObjSize, + storageSize: collectionInfo.storageSize, + totalIndexSize: collectionInfo.totalIndexSize, + indexSizes: collectionInfo.indexSizes, + }; + }); + + stats.mem = serverStatus.mem || {}; + stats.mem.resident = (stats.mem.resident / 1024).toFixed(3); + stats.mem.virtual = (stats.mem.virtual / 1024).toFixed(3); + stats.mem.mapped = (stats.mem.mapped / 1024).toFixed(3); + stats.collectionData = listCollections; + stats.network = serverStatus.network || {}; + stats.network.bytesIn = (stats.network.bytesIn / scale).toFixed(3); + stats.network.bytesOut = (stats.network.bytesOut / scale).toFixed(3); + stats.network.numRequests = utils.addCommas(stats.network.numRequests); + stats.raw = JSON.stringify(stats, null, 4); + + stats.avgObjSize = stats.avgObjSize.toFixed(2); + stats.dataSize = (stats.dataSize / scale).toFixed(3); + stats.storageSize = (stats.storageSize / scale).toFixed(3); + stats.fileSize = stats.fileSize ? (stats.fileSize / scale).toFixed(3) : 0; + stats.indexSize = (stats.indexSize / scale).toFixed(3); + stats.storageEngine = serverStatus.storageEngine ? serverStatus.storageEngine.name : 'mmapv1'; + stats.host = serverStatus.host; + stats.version = serverStatus.version; + stats.uptime = serverStatus.uptime; + stats.mongo = true; + return stats; }; -function getCollectionStats(db, callback) { - async.waterfall([ - function (next) { - db.listCollections().toArray(next); - }, - function (items, next) { - async.map(items, function (collection, next) { - db.collection(collection.name).stats(next); - }, next); - }, - ], callback); +async function getCollectionStats(db) { + const items = await db.listCollections().toArray(); + return await Promise.all(items.map(collection => db.collection(collection.name).stats)); } mongoModule.close = function (callback) { callback = callback || function () {}; - client.close(function (err) { - callback(err); - }); + client.close(err => callback(err)); }; mongoModule.socketAdapter = function () { - var mongoAdapter = require('socket.io-adapter-mongo'); + const mongoAdapter = require('socket.io-adapter-mongo'); return mongoAdapter(connection.getConnectionString()); }; diff --git a/src/database/mongo/connection.js b/src/database/mongo/connection.js index 3b0a32573a..cd380bddef 100644 --- a/src/database/mongo/connection.js +++ b/src/database/mongo/connection.js @@ -56,13 +56,11 @@ connection.getConnectionOptions = function (mongo) { return _.merge(connOptions, mongo.options || {}); }; -connection.connect = function (options, callback) { - callback = callback || function () { }; - +connection.connect = async function (options) { const mongoClient = require('mongodb').MongoClient; const connString = connection.getConnectionString(options); const connOptions = connection.getConnectionOptions(options); - mongoClient.connect(connString, connOptions, callback); + return await mongoClient.connect(connString, connOptions); };