      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;