mysql-queue-pool
Version:
Database connection pooling and query queueing.
131 lines (111 loc) • 2.42 kB
JavaScript
/**
* Connection pool.
*
* @file utils/pool.js
* @author Radek Pycka
*
* @todo implement timeouts
*/
var _ = require('underscore')._;
/**
* @private
* @param {Object} config
*/
function ConnectionPool(config) {
this.constructor = config.constructor;
this.maxSize = config.maxSize;
this.cptr = 0;
this.pool = [];
this.queue = [];
this.timeout = config.timeout;
}
/**
* Acquire connection from the pool in round-robin fashion.
*
* @param {Function} callback
*/
ConnectionPool.prototype.acquire = function (callback) {
var pool = this.pool;
var cptr = this.cptr;
var size = pool.length;
var i = cptr;
var item;
if (size) {
do {
i = ++i % size;
item = pool[i];
if (!item.locked) {
item.lock();
_.defer(callback, null, item.object);
this.cptr = i;
return;
}
}
while(i !== cptr);
}
// Nothing found, establish new connection or join waiting.
if (size < this.maxSize) {
var me = this;
var object = this.constructor(function (err) {
if (err) {
me.release(object, true);
console.log('DBM ' + err);
}
_.defer(callback, err, object);
});
pool.push(new Item(object));
}
else {
this.queue.push(callback);
}
};
/**
* Return acquired object to the pool.
*
* @public
* @idempotent
*
* @param {Object} object
* @param {Boolean} remove
* Whether to remove permanently object from the pool.
*/
ConnectionPool.prototype.release = function (object, remove) {
for (var i = 0, max = this.pool.length ; i < max ; ++i) {
var item = this.pool[i];
if (item.object === object) {
if (remove) {
this.pool.splice(i, 1);
}
else if (this.queue.length) { // someone is waiting for connection
_.defer(this.queue.shift, null, object);
}
else {
item.unlock();
}
break;
}
}
};
/**
* Wrapper around held object.
*
* @param {Object} object
*/
function Item (object) {
this.object = object;
this.locked = true;
}
/**
* @public
*/
Item.prototype.lock = function () {
this.locked = true;
};
/**
* @public
*/
Item.prototype.unlock = function () {
this.locked = false;
};
// Export public API.
exports.ConnectionPool = ConnectionPool;