Permalink
Browse files

Merge pull request #54 from tikonen/master

Factory can be asked to validate pooled objects
  • Loading branch information...
2 parents 69992f7 + 1216a10 commit a6db3afe7b939e23386c5126e37fd0e22c39be79 @coopernurse committed Jan 17, 2013
Showing with 45 additions and 6 deletions.
  1. +17 −6 lib/generic-pool.js
  2. +28 −0 test/generic-pool.test.js
View
@@ -70,11 +70,15 @@ var PriorityQueue = function(size) {
* @param {Function} factory.destroy
* Should gently close any resources that the item is using.
* Called before the items is destroyed.
+ * @param {Function} factory.validate
+ * Should return true if connection is still valid and false
+ * If it should be removed from pool. Called before item is
+ * acquired from pool.
* @param {Number} factory.max
- * Maximum numnber of items that can exist at the same time. Default: 1.
+ * Maximum number of items that can exist at the same time. Default: 1.
* Any further acquire requests will be pushed to the waiting list.
* @param {Number} factory.min
- * Minimum numnber of items in pool (including in-use). Default: 0.
+ * Minimum number of items in pool (including in-use). Default: 0.
* When the pool is created, or a resource destroyed, this minimum will
* be checked. If the pool resource count is below the minimum, a new
* resource will be created and added to the pool.
@@ -118,6 +122,8 @@ exports.Pool = function (factory) {
) :
function () {};
+ factory.validate = factory.validate || function() { return true; };
+
factory.max = parseInt(factory.max, 10);
factory.min = parseInt(factory.min, 10);
@@ -229,13 +235,18 @@ exports.Pool = function (factory) {
log("dispense() clients=" + waitingCount + " available=" + availableObjects.length, 'info');
if (waitingCount > 0) {
- if (availableObjects.length > 0) {
+ while (availableObjects.length > 0) {
log("dispense() - reusing obj", 'verbose');
- objWithTimeout = availableObjects.shift();
+ objWithTimeout = availableObjects[0];
+ if (!factory.validate(objWithTimeout.obj)) {
+ me.destroy(objWithTimeout.obj);
+ continue;
+ }
+ availableObjects.shift();
clientCb = waitingClients.dequeue();
- clientCb(err, objWithTimeout.obj);
+ return clientCb(err, objWithTimeout.obj);
}
- else if (count < factory.max) {
+ if (count < factory.max) {
createResource();
}
}
@@ -559,6 +559,34 @@ module.exports = {
assert.equal(pool.availableObjectsCount(), 0);
},
+ 'removes from available objects on validation failure': function(beforeExit){
+ var destroyCalled = false,
+ validateCalled = false,
+ count = 0;
+ var factory = {
+ name: 'test',
+ create: function(callback) {callback(null, {count: count++}); },
+ destroy: function(client) {destroyCalled = client.count; },
+ validate: function(client) {validateCalled = true; return client.count != 0;},
+ max: 2,
+ idleTimeoutMillis: 100
+ };
+
+ var pool = poolModule.Pool(factory);
+ pool.acquire(function(err, obj){
+ pool.release(obj);
+ assert.equal(obj.count, 0);
+
+ pool.acquire(function(err, obj){
+ pool.release(obj);
+ assert.equal(obj.count, 1);
+ });
+ });
+ assert.equal(validateCalled, true);
+ assert.equal(destroyCalled, 0);
+ assert.equal(pool.availableObjectsCount(), 1);
+ },
+
'do schedule again if error occured when creating new Objects async': function(beforeExit){
var factory = {
name: 'test',

0 comments on commit a6db3af

Please sign in to comment.