需要我模块的多个文件会覆盖它的变量

时间:2014-08-28 21:08:10

标签: javascript node.js node-mongodb-native

我尝试创建一个mongo连接池工厂,检查是否已存在与mongo的连接并返回连接。如果它没有创建连接池并返回连接。

我希望能够从多个要查询mongo的文件中要求这个。每个文件都应该像这样需要mongo:

var fooMongoFactory = require('../../lib/mongoFactory').init(mongodb://localhost:27017/foo);

然后你在文件中使用它:

fooMongoFactory.getConnection().then(function(db) {
  // do stuff
});

我遇到的问题是我希望能够在文件中指定多个不同的mongo实例,但是在执行此操作时,我的第二个init会覆盖第一个。例如:

var fooMongoFactory = require('../../lib/mongoFactory').init(mongodb://localhost:27017/foo);
var barMongoFactory = require('../../lib/mongoFactory').init(mongodb://localhost:27017/bar);

fooMongoFactory.getConnection().then(function(db) {
  // querying in here is actually pointing at the mongo db "bar"
});

如何调整我的工厂以便我可以连接到多个不同的mongo实例,以及跨多个文件使用同一个工厂而不必每次都实例化它?我想过使用构造函数,但是会在每个使用mongoFactory的文件中创建一个新的连接池。

/**
 * Creates and manages the Mongo connection pool
 *
 * @type {exports}
 */
var Q = require('q');
var MongoClient = require('mongodb').MongoClient;
var dbPromise = null;
var db = null;

module.exports = function() {

  return {

    init: function init(connectionString) {
      db = connectionString;
      return module.exports;
    },

    /**
     * Gets a connection to Mongo from the pool. If the pool has not been instantiated it,
     *    instantiates it and returns a connection. Else it just returns a connection from the pool
     *
     * @returns {*}   - A promise object that will resolve to a mongo db object
     */
    getConnection: function getConnection() {
      // get a connection to mongo using the db string and return dbPromise 
    }
  }
}();

2 个答案:

答案 0 :(得分:1)

mongodb节点模块已具有built-in connection pooling功能,当您致电connect()时,该功能会自动使用。 default max connection pool size is 5,但您可以在连接网址中更改此值(例如'mongodb://localhost:27017/foo?maxPoolSize=15')。

您还希望通过将server config options中的poolSize设置为小于或等于maxPoolSize的某个值来更改创建的实际连接数。您可能还想将auto_reconnect设置为true。

现在你可以做的是保持一个对象键在host:port上,该对象包含该服务器的数据库对象。如果有人传入包含对象中host:port的连接字符串,则返回池。否则,创建,缓存并返回新的数据库对象。

答案 1 :(得分:0)

我最终创建了模块,因此您必须传入要连接的mongodb的连接字符串。该模块最终跟踪已经对mongo进行的所有连接以及是否存在与传入的mongodb的当前连接。

/**
 * Creates and manages the Mongo connection pool
 *
 * @type {exports}
 */
var Q = require('q');
var MongoClient = require('mongodb').MongoClient;
var _ = require('underscore');

var connections = [];
var dbPromise = null;

module.exports = function() {

  return {

    /**
     * Gets a connection to Mongo from the pool. If the pool has not been instantiated it,
     *    instantiates it and returns a connection. Else it just returns a connection from the pool
     *
     * @returns {*}   - A promise object that will resolve to a mongo db object
     */
    getConnection: function getConnection(connectionString) {

      var def = Q.defer();

            // If connectionString is null or undefined, return an error
            if(_.isEmpty(connectionString)) {
                def.reject('getConnection must contain a first parameter');
                return dbPromise = def.promise;
            }

      // Check if connections contains an object with connectionString equal to the connectionString passed in and set the var to it
      var pool = _.findWhere(connections, {connectionString: connectionString});

      // If no conneciton pool has been instantiated, instantiate it, else return a connection from the pool
      if(_.isUndefined(pool)) {

        // Initialize connection once
        MongoClient.connect(connectionString, function(err, database) {
          if (err) {
            def.reject(err);
          }

          // Add the connection to the array
          connections.push({connectionString: connectionString, db: database});

          def.resolve(database);
        });

      } else {  // Else we have not instantiated the pool yet and we need to
        def.resolve(pool.db);
      }

      return dbPromise = def.promise;
    }
  };
}();

https://github.com/toymachiner62/mongo-factory