UNPKG

mysql-queue-pool

Version:

Database connection pooling and query queueing.

131 lines (111 loc) 2.42 kB
/** * 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;