From f7f9db17b08529234ed5e02188c1273d96f527ad Mon Sep 17 00:00:00 2001 From: Benjamin Pannell Date: Mon, 24 Aug 2015 07:45:41 +0200 Subject: [PATCH] Make core.connect async-safe (Fixes #15) Only a single MongoDB connection will be opened regardless of how many times connect is called, and regardless of the delay between calling connect and it actually resolving. --- dist/lib/Core.js | 8 +++++++- dist/lib/Core.js.map | 2 +- lib/Core.ts | 13 ++++++++++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/dist/lib/Core.js b/dist/lib/Core.js index f39bfbb..b33ece0 100644 --- a/dist/lib/Core.js +++ b/dist/lib/Core.js @@ -133,10 +133,16 @@ var Core = (function () { return Bluebird.bind(this).then(function () { if (self._connection) return self._connection; - return mongoConnectAsyc(self.url); + if (self._connectPromise) + return this._connectPromise; + return self._connectPromise = mongoConnectAsyc(self.url); }).then(function (db) { self._connection = db; + self._connectPromise = null; return self; + }, function (err) { + self._connectPromise = null; + return Bluebird.reject(err); }).nodeify(callback); }; /** diff --git a/dist/lib/Core.js.map b/dist/lib/Core.js.map index 5ed979e..748658e 100644 --- a/dist/lib/Core.js.map +++ b/dist/lib/Core.js.map @@ -1 +1 @@ -{"version":3,"sources":["lib/Core.ts"],"names":["Core","Core.constructor","Core.plugins","Core.settings","Core.connection","Core.url","Core.cache","Core.register","Core.connect","Core.close","Core.express"],"mappings":"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","file":"lib/Core.js","sourcesContent":["/// \r\nimport Bluebird = require('bluebird');\r\nimport MongoDB = require('mongodb');\r\nimport _ = require('lodash');\r\nimport http = require('http');\r\nimport events = require('events');\r\n\r\nimport {Configuration} from './Configuration';\r\nimport {Plugin} from './Plugins';\r\nimport Model from './Model';\r\nimport Instance from './Instance';\r\n\r\nimport {MiddlewareFactory} from './Middleware';\r\nimport * as ExpressMiddleware from './middleware/Express';\r\nimport ExpressMiddlewareFactory from './middleware/Express';\r\n\r\nimport {Cache} from './Cache';\r\nimport NoOpCache from './caches/NoOpCache';\r\nimport MemoryCache from './caches/MemoryCache';\r\n\r\nvar mongoConnectAsyc = Bluebird.promisify(MongoDB.MongoClient.connect);\r\n\r\nexport default class Core {\r\n /**\r\n * Creates a new Iridium Core instance connected to the specified MongoDB instance\r\n * @param {Iridium.IridiumConfiguration} config The config object defining the database to connect to\r\n * @constructs Core\r\n */\r\n constructor(config: Configuration);\r\n /**\r\n * Creates a new Iridium Core instance connected to the specified MongoDB instance\r\n * @param {String} url The URL of the MongoDB instance to connect to\r\n * @param {Iridium.IridiumConfiguration} config The config object made available as settings\r\n * @constructs Core\r\n */\r\n constructor(uri: string, config?: Configuration);\r\n constructor(uri: string | Configuration, config?: Configuration) {\r\n\r\n var args = Array.prototype.slice.call(arguments, 0);\r\n uri = config = null;\r\n for (var i = 0; i < args.length; i++) {\r\n if (typeof args[i] == 'string')\r\n uri = args[i];\r\n else if (typeof args[i] == 'object')\r\n config = args[i];\r\n }\r\n\r\n if (!uri && !config) throw new Error(\"Expected either a URI or config object to be supplied when initializing Iridium\");\r\n\r\n this._url = uri;\r\n this._config = config;\r\n }\r\n \r\n private _plugins: Plugin[] = [];\r\n private _url: string;\r\n private _config: Configuration;\r\n private _connection: MongoDB.Db;\r\n private _cache: Cache = new NoOpCache();\r\n \r\n /**\r\n * Gets the plugins registered with this Iridium Core\r\n * @returns {[Iridium.Plugin]}\r\n */\r\n get plugins(): Plugin[] {\r\n return this._plugins;\r\n }\r\n\r\n /**\r\n * Gets the configuration specified in the construction of this\r\n * Iridium Core.\r\n * @returns {Iridium.Configuration}\r\n */\r\n get settings(): Configuration {\r\n return this._config;\r\n }\r\n\r\n /**\r\n * Gets the currently active database connection for this Iridium\r\n * Core.\r\n * @returns {MongoDB.Db}\r\n */\r\n get connection(): MongoDB.Db {\r\n return this._connection;\r\n }\r\n\r\n /**\r\n * Gets the URL used to connect to MongoDB\r\n * @returns {String}\r\n */\r\n get url(): string {\r\n if (this._url) return this._url;\r\n var url: string = 'mongodb://';\r\n\r\n if (this._config.username) {\r\n url += this._config.username;\r\n if (this._config.password)\r\n url += ':' + this._config.password;\r\n url += '@';\r\n }\r\n\r\n var hosts = [];\r\n\r\n if (this._config.host) {\r\n if (this._config.port)\r\n hosts.push(this._config.host + ':' + this._config.port);\r\n else\r\n hosts.push(this._config.host);\r\n }\r\n\r\n if (this._config.hosts) {\r\n _.each(this._config.hosts, (host) => {\r\n if (host.port)\r\n hosts.push(host.address + ':' + host.port);\r\n else if(this._config.port)\r\n hosts.push(host.address + ':' + this._config.port);\r\n else\r\n hosts.push(host.address);\r\n });\r\n }\r\n\r\n if (hosts.length)\r\n url += _.uniq(hosts).join(',');\r\n else\r\n url += 'localhost';\r\n\r\n url += '/' + this._config.database;\r\n\r\n return url;\r\n }\r\n\r\n /**\r\n * Gets the cache used to store objects retrieved from the database for performance reasons\r\n * @returns {cache}\r\n */\r\n get cache(): Cache {\r\n return this._cache;\r\n }\r\n\r\n set cache(value: Cache) {\r\n this._cache = value;\r\n }\r\n\r\n /**\r\n * Registers a new plugin with this Iridium Core\r\n * @param {Iridium.Plugin} plugin The plugin to register with this Iridium Core\r\n * @returns {Iridium.Core}\r\n */\r\n register(plugin: Plugin): Core {\r\n this.plugins.push(plugin);\r\n return this;\r\n }\r\n\r\n /**\r\n * Connects to the database server specified in the provided configuration\r\n * @param {function(Error, Iridium.Core)} [callback] A callback to be triggered once the connection is established.\r\n * @returns {Promise}\r\n */\r\n connect(callback?: (err: Error, core: Core) => any): Bluebird {\r\n var self = this;\r\n return Bluebird.bind(this).then(function() {\r\n if (self._connection) return self._connection;\r\n return mongoConnectAsyc(self.url);\r\n }).then(function(db: MongoDB.Db) {\r\n self._connection = db;\r\n return self;\r\n }).nodeify(callback);\r\n }\r\n\r\n /**\r\n * Closes the active database connection\r\n * @type {Promise}\r\n */\r\n close(): Bluebird {\r\n var self = this;\r\n return Bluebird.bind(this).then(function() {\r\n if (!self._connection) return this;\r\n var conn: MongoDB.Db = self._connection;\r\n self._connection = null;\r\n conn.close();\r\n return this;\r\n });\r\n }\r\n\r\n /**\r\n * Provides an express middleware which can be used to set the req.db property\r\n * to the current Iridium instance.\r\n * @returns {Iridium.ExpressMiddleware}\r\n */\r\n express(): ExpressMiddleware.ExpressMiddleware {\r\n return ExpressMiddlewareFactory(this);\r\n }\r\n}\r\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["lib/Core.ts"],"names":["Core","Core.constructor","Core.plugins","Core.settings","Core.connection","Core.url","Core.cache","Core.register","Core.connect","Core.close","Core.express"],"mappings":"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","file":"lib/Core.js","sourcesContent":["/// \r\nimport Bluebird = require('bluebird');\r\nimport MongoDB = require('mongodb');\r\nimport _ = require('lodash');\r\nimport http = require('http');\r\nimport events = require('events');\r\n\r\nimport {Configuration} from './Configuration';\r\nimport {Plugin} from './Plugins';\r\nimport Model from './Model';\r\nimport Instance from './Instance';\r\n\r\nimport {MiddlewareFactory} from './Middleware';\r\nimport * as ExpressMiddleware from './middleware/Express';\r\nimport ExpressMiddlewareFactory from './middleware/Express';\r\n\r\nimport {Cache} from './Cache';\r\nimport NoOpCache from './caches/NoOpCache';\r\nimport MemoryCache from './caches/MemoryCache';\r\n\r\nvar mongoConnectAsyc = Bluebird.promisify(MongoDB.MongoClient.connect);\r\n\r\nexport default class Core {\r\n /**\r\n * Creates a new Iridium Core instance connected to the specified MongoDB instance\r\n * @param {Iridium.IridiumConfiguration} config The config object defining the database to connect to\r\n * @constructs Core\r\n */\r\n constructor(config: Configuration);\r\n /**\r\n * Creates a new Iridium Core instance connected to the specified MongoDB instance\r\n * @param {String} url The URL of the MongoDB instance to connect to\r\n * @param {Iridium.IridiumConfiguration} config The config object made available as settings\r\n * @constructs Core\r\n */\r\n constructor(uri: string, config?: Configuration);\r\n constructor(uri: string | Configuration, config?: Configuration) {\r\n\r\n var args = Array.prototype.slice.call(arguments, 0);\r\n uri = config = null;\r\n for (var i = 0; i < args.length; i++) {\r\n if (typeof args[i] == 'string')\r\n uri = args[i];\r\n else if (typeof args[i] == 'object')\r\n config = args[i];\r\n }\r\n\r\n if (!uri && !config) throw new Error(\"Expected either a URI or config object to be supplied when initializing Iridium\");\r\n\r\n this._url = uri;\r\n this._config = config;\r\n }\r\n\r\n private _plugins: Plugin[] = [];\r\n private _url: string;\r\n private _config: Configuration;\r\n private _connection: MongoDB.Db;\r\n private _cache: Cache = new NoOpCache();\r\n\r\n private _connectPromise: Bluebird;\r\n\r\n /**\r\n * Gets the plugins registered with this Iridium Core\r\n * @returns {[Iridium.Plugin]}\r\n */\r\n get plugins(): Plugin[] {\r\n return this._plugins;\r\n }\r\n\r\n /**\r\n * Gets the configuration specified in the construction of this\r\n * Iridium Core.\r\n * @returns {Iridium.Configuration}\r\n */\r\n get settings(): Configuration {\r\n return this._config;\r\n }\r\n\r\n /**\r\n * Gets the currently active database connection for this Iridium\r\n * Core.\r\n * @returns {MongoDB.Db}\r\n */\r\n get connection(): MongoDB.Db {\r\n return this._connection;\r\n }\r\n\r\n /**\r\n * Gets the URL used to connect to MongoDB\r\n * @returns {String}\r\n */\r\n get url(): string {\r\n if (this._url) return this._url;\r\n var url: string = 'mongodb://';\r\n\r\n if (this._config.username) {\r\n url += this._config.username;\r\n if (this._config.password)\r\n url += ':' + this._config.password;\r\n url += '@';\r\n }\r\n\r\n var hosts = [];\r\n\r\n if (this._config.host) {\r\n if (this._config.port)\r\n hosts.push(this._config.host + ':' + this._config.port);\r\n else\r\n hosts.push(this._config.host);\r\n }\r\n\r\n if (this._config.hosts) {\r\n _.each(this._config.hosts, (host) => {\r\n if (host.port)\r\n hosts.push(host.address + ':' + host.port);\r\n else if(this._config.port)\r\n hosts.push(host.address + ':' + this._config.port);\r\n else\r\n hosts.push(host.address);\r\n });\r\n }\r\n\r\n if (hosts.length)\r\n url += _.uniq(hosts).join(',');\r\n else\r\n url += 'localhost';\r\n\r\n url += '/' + this._config.database;\r\n\r\n return url;\r\n }\r\n\r\n /**\r\n * Gets the cache used to store objects retrieved from the database for performance reasons\r\n * @returns {cache}\r\n */\r\n get cache(): Cache {\r\n return this._cache;\r\n }\r\n\r\n set cache(value: Cache) {\r\n this._cache = value;\r\n }\r\n\r\n /**\r\n * Registers a new plugin with this Iridium Core\r\n * @param {Iridium.Plugin} plugin The plugin to register with this Iridium Core\r\n * @returns {Iridium.Core}\r\n */\r\n register(plugin: Plugin): Core {\r\n this.plugins.push(plugin);\r\n return this;\r\n }\r\n\r\n /**\r\n * Connects to the database server specified in the provided configuration\r\n * @param {function(Error, Iridium.Core)} [callback] A callback to be triggered once the connection is established.\r\n * @returns {Promise}\r\n */\r\n connect(callback?: (err: Error, core: Core) => any): Bluebird {\r\n var self = this;\r\n return Bluebird.bind(this).then(function() {\r\n if (self._connection) return self._connection;\r\n if (self._connectPromise) return this._connectPromise;\r\n return self._connectPromise = mongoConnectAsyc(self.url);\r\n }).then(function(db: MongoDB.Db) {\r\n self._connection = db;\r\n self._connectPromise = null;\r\n return self;\r\n }, function(err) {\r\n self._connectPromise = null;\r\n return Bluebird.reject(err);\r\n }).nodeify(callback);\r\n }\r\n\r\n /**\r\n * Closes the active database connection\r\n * @type {Promise}\r\n */\r\n close(): Bluebird {\r\n var self = this;\r\n return Bluebird.bind(this).then(function() {\r\n if (!self._connection) return this;\r\n var conn: MongoDB.Db = self._connection;\r\n self._connection = null;\r\n conn.close();\r\n return this;\r\n });\r\n }\r\n\r\n /**\r\n * Provides an express middleware which can be used to set the req.db property\r\n * to the current Iridium instance.\r\n * @returns {Iridium.ExpressMiddleware}\r\n */\r\n express(): ExpressMiddleware.ExpressMiddleware {\r\n return ExpressMiddlewareFactory(this);\r\n }\r\n}\r\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/lib/Core.ts b/lib/Core.ts index d6822bb..71f3d69 100644 --- a/lib/Core.ts +++ b/lib/Core.ts @@ -50,13 +50,15 @@ export default class Core { this._url = uri; this._config = config; } - + private _plugins: Plugin[] = []; private _url: string; private _config: Configuration; private _connection: MongoDB.Db; private _cache: Cache = new NoOpCache(); - + + private _connectPromise: Bluebird; + /** * Gets the plugins registered with this Iridium Core * @returns {[Iridium.Plugin]} @@ -159,10 +161,15 @@ export default class Core { var self = this; return Bluebird.bind(this).then(function() { if (self._connection) return self._connection; - return mongoConnectAsyc(self.url); + if (self._connectPromise) return this._connectPromise; + return self._connectPromise = mongoConnectAsyc(self.url); }).then(function(db: MongoDB.Db) { self._connection = db; + self._connectPromise = null; return self; + }, function(err) { + self._connectPromise = null; + return Bluebird.reject(err); }).nodeify(callback); }