1 var comb = require("comb"); 2 3 4 /** 5 * @class Base class for all connection pools 6 * 7 * @name ConnectionPool 8 * @augments comb.collections.Pool 9 * @memberOf moose.adapters.client 10 */ 11 var ConnectionPool = comb.define(comb.collections.Pool, { 12 13 instance : { 14 /**@lends moose.adapters.client.ConnectionPool.prototype*/ 15 16 constructor : function(options) { 17 options = options || {}; 18 if (!options.database) throw "moose.adapters.clients.ConnectionPool : a database is required to initialize the pool."; 19 options.minObjects = options.minConnections || 0; 20 options.maxObjects = options.maxConnections || 10; 21 this.database = options.database; 22 this.__deferredQueue = new comb.collections.Queue(); 23 this._options = options; 24 this.super(arguments); 25 }, 26 27 /** 28 * Checks all deferred connection requests. 29 */ 30 __checkQueries : function() { 31 var fc = this.freeCount, def, defQueue = this.__deferredQueue; 32 while (fc-- >= 0 && defQueue.count) { 33 def = defQueue.dequeue(); 34 var conn = this.getObject(); 35 if (conn) { 36 def.callback(conn); 37 } else { 38 //we didnt get a conneciton so assume we're out. 39 break; 40 } 41 fc--; 42 } 43 }, 44 45 /** 46 * Performs a query on one of the connection in this Pool. 47 * 48 * @return {comb.Promise} A promise to called back with a connection. 49 */ 50 getConnection : function() { 51 var ret = new comb.Promise(); 52 var conn = this.getObject(); 53 if (!conn) { 54 //we need to deffer it 55 this.__deferredQueue.enqueue(ret); 56 } else { 57 ret.callback(conn); 58 } 59 return ret; 60 }, 61 62 /** 63 * Override comb.collections.Pool to allow async validation to allow 64 * pools to do any calls to reset a connection if it needs to be done. 65 * 66 * @param {*} connection the connection to return. 67 * 68 */ 69 returnObject : function(obj) { 70 if (this.count <= this.__maxObjects) { 71 this.validate(obj).then(comb.hitch(this, function(valid) { 72 if (valid) { 73 this.__freeObjects.enqueue(obj); 74 var index; 75 if ((index = this.__inUseObjects.indexOf(obj)) > -1) 76 this.__inUseObjects.splice(index, 1); 77 this.__checkQueries(); 78 } else { 79 this.removeObject(obj); 80 } 81 })); 82 } else { 83 this.removeObject(obj); 84 } 85 }, 86 87 /** 88 * Removes a connection from the pool. 89 * @param conn 90 */ 91 removeConnection : function(conn){ 92 this.removeObject(conn); 93 }, 94 95 /** 96 * Return a connection to the pool. 97 * 98 * @param {*} connection the connection to return. 99 * 100 * @return {*} an adapter specific connection. 101 */ 102 returnConnection : function(connection) { 103 this.returnObject(connection); 104 }, 105 106 createObject : function() { 107 return this.createConnection(); 108 }, 109 110 /** 111 * Override to implement the closing of all connections. 112 * 113 * @return {comb.Promise} called when all connections are closed. 114 */ 115 endAll : function() { 116 this.__ending = true; 117 var conn, fQueue = this.__freeObjects, count = this.count, ps = []; 118 while ((conn = this.__freeObjects.dequeue()) != undefined) { 119 ps.push(this.closeConnection(conn)); 120 } 121 var inUse = this.__inUseObjects; 122 for (var i = inUse.length - 1; i >= 0; i--) { 123 ps.push(this.closeConnection(inUse[i])); 124 } 125 this.__inUseObjects.length = 0; 126 var pls = new comb.PromiseList(ps); 127 return pls; 128 }, 129 130 131 /** 132 * Override to provide any additional validation. By default the promise is called back with true. 133 * 134 * @param {*} connection the conneciton to validate. 135 * 136 * @return {comb.Promise} called back with a valid or invalid state. 137 */ 138 validate : function(conn) { 139 var ret = new comb.Promise(); 140 ret.callback(true); 141 return ret; 142 }, 143 144 /** 145 * Override to create connections to insert into this ConnectionPool. 146 */ 147 createConnection : function() { 148 throw "moose.adapters.clients.ConnectionPool : createConnection not implemented."; 149 }, 150 151 /** 152 * Override to implement close connection functionality; 153 * @param {*} conn the connection to close; 154 * 155 * @return {comb.Promise} called back when the connection is closed. 156 */ 157 closeConnection : function(conn) { 158 throw "moose.adapters.clients.ConnectionPool : closeConnection not implemented."; 159 } 160 } 161 162 }); 163 exports = module.exports = ConnectionPool;