pongo
Version:
Connection pooling for node-mongodb-native
181 lines (141 loc) • 4.39 kB
JavaScript
var mongo = require("mongodb");
var DEFAULT_HOST = "127.0.0.1";
var DEFAULT_PORT = 27017;
var DEFAULT_BUFFERSIZE = 100;
/**
* Pongo constructor.
*
* ####Example:
*
* var pongo = new Pongo({
* server: {poolSize: 3},
* db: {w: 1}
* });
*
* ####Options:
*
* - [host]: string - defaults to '127.0.0.1'
* - [port]: number - defaults to 27017
* - [bufferSize]: number - defaults to 100
* - [server]: object - defaults from http://mongodb.github.com/node-mongodb-native/api-generated/server.html?highlight=server#server
* - [db]: object - defaults from http://mongodb.github.com/node-mongodb-native/api-generated/db.html?highlight=db#db
*
* @param {Object} options
* @api public
*/
function Pongo (options) {
options = options || {};
this.host = options.host || DEFAULT_HOST;
this.port = options.port || DEFAULT_PORT;
this.pool = {};
this.buffer = {};
this.MAX_CALLBACKS_IN_BUFFER = options.bufferSize || DEFAULT_BUFFERSIZE;
if (options.server) {
this.serverOptions = options.server;
}
if (options.db) {
this.dbOptions = options.db;
}
}
function callbacks (err) {
for (var dbName in this.buffer) {
if (!this.pool[dbName] && this._Db) {
//cache db instance
this.pool[dbName] = this._Db.db(dbName);
}
var length = this.buffer[dbName].length;
//execute callbacks in buffer
if (length > 0) {
for (var i = 0; i < length; ++i) {
this.buffer[dbName][i](err, this.pool[dbName]);
}
}
this.buffer[dbName] = [];
}
}
function bufferCallback (dbName, callback) {
if (!this.buffer[dbName]) {
this.buffer[dbName] = [];
}
if (this.buffer[dbName].length < this.MAX_CALLBACKS_IN_BUFFER) {
this.buffer[dbName].push(callback);
}
else {
callback(new Error("Number of callbacks in buffer exceeded."));
}
}
Pongo.prototype = mongo;
/**
* Pongo connect.
*
* ####Example:
*
* pongo.connect('myMongoDb', function (err, db) {
* // use the db instance as you would with the https://github.com/mongodb/node-mongodb-native driver.
* });
*
* pongo.connect('myOtherMongoDb', function (err, db) {
* // use the db instance as you would with the https://github.com/mongodb/node-mongodb-native driver.
* });
*
* ####Options:
*
* - [dbName]: string - no default
* - [callback]: function - no default\
*
* ####Note:
*
* No more sockets are opened, as defined in the server.poolSize option.
*
* @param {Object} options
* @api public
*/
Pongo.prototype.connect = function (dbName, callback) {
// return Db instance, if allready in pool
if (this.pool[dbName]) {
return callback(null, this.pool[dbName]);
}
// buffer callbacks when db is connecting
if (this.pool[dbName] === null) {
return bufferCallback.call(this, dbName, callback);
}
this.pool[dbName] = null;
// buffer the callback
bufferCallback.call(this, dbName, callback);
// return if Db is opening
if (this._Db === null) {
return;
}
// create connection
if (!this._Db) {
this._Db = null;
var self = this;
new mongo.Db(
dbName,
new mongo.Server(
this.host,
this.port,
this.serverOptions
),
this.dbOptions
).open(function (err, db) {
if (err) {
return callbacks.call(self, err);
}
// save db ref
self._Db = db;
//cache db
self.pool[dbName] = db;
//retrun collection
callbacks.call(self, null);
});
// Create a new Db instance sharing the current socket connections.
// http://mongodb.github.com/node-mongodb-native/api-generated/db.html?highlight=db#id1
} else {
this.pool[dbName] = this._Db.db(dbName);
callbacks.call(this, null);
}
};
// export object id class
Pongo.ObjectId = mongo.ObjectID;
module.exports = Pongo;