2014-08-28 57 views
1

我想創建一個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" 
}); 

我如何調整我的工廠,這樣我可以連接到蒙戈的多個不同的實例,以及使用在多個文件這同一個工廠,而不必每次都實例化了嗎?我想過使用構造函數,但是它會在每個使用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 
    } 
    } 
}(); 
+1

凡/如何'init'叫什麼名字? – 2014-08-28 21:18:13

+0

在需要mongoFactory後調用Init。 Init只是設置調用腳本調用getConnection時使用的db變量。 'getConnection'使用之前設置的'db'變量。 – Catfish 2014-08-28 21:28:36

+0

只是命名「工廠」並不能使它成爲工廠。 http://en.wikipedia.org/wiki/Factory_method_pattern – 2014-08-28 21:30:45

回答

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

1

mongodb節點模塊已經有了,當你調用connect()時自動使用built-in connection pooling功能。 default max connection pool size is 5,但是您可以在連接URL中更改此值(例如'mongodb://localhost:27017/foo?maxPoolSize=15')。

您還需要更改通過在server config options中將poolSize設置爲小於或等於maxPoolSize的某個值創建的實際連接數。您可能還想將auto_reconnect設置爲true。

現在你可以做的是保持一個對象在主機上:包含該服務器的數據庫對象的端口。如果有人傳入包含主機端口的連接字符串,則返回該池。否則,創建,緩存並返回新的數據庫對象。

+0

我知道它內置了連接池,但是如果你有兩個文件,每個文件都會調用'connect()'來創建2個連接。我試圖通過創建這個mongoFactory來避免這種情況。一個用例是有一個網頁,可以對我的後端進行多個Web服務調用。那麼,如果每個Web服務調用都調用調用'connect()'的不同文件,那麼現在我打開了多個連接池。 – Catfish 2014-08-28 23:27:35