Skip to content

Commit

Permalink
Validate objects when calling release()
Browse files Browse the repository at this point in the history
Previous implementation of `release()` allows passing any arbitrary
object which will be pushed back to the pool without any validation.
This behavior makes subsequent calls to `acquire()` fail. This commit
fixes that by adding acquired objects to an `inUseObjects` list and
check for valid objects when calling `release()`.
  • Loading branch information
Ryan Dao committed Nov 21, 2015
1 parent 8984c31 commit 7eef89d
Showing 1 changed file with 26 additions and 5 deletions.
31 changes: 26 additions & 5 deletions lib/generic-pool.js
Expand Up @@ -105,6 +105,7 @@ exports.Pool = function (factory) {
reapInterval = factory.reapIntervalMillis || 1000,
refreshIdle = ('refreshIdle' in factory) ? factory.refreshIdle : true,
availableObjects = [],
inUseObjects = [],
waitingClients = new PriorityQueue(factory.priorityRange || 1),
count = 0,
removeIdleScheduled = false,
Expand Down Expand Up @@ -150,6 +151,11 @@ exports.Pool = function (factory) {
availableObjects = availableObjects.filter(function(objWithTimeout) {
return (objWithTimeout.obj !== obj);
});

inUseObjects = inUseObjects.filter(function(obj) {
return (obj !== obj);
});

factory.destroy(obj);

ensureMinimum();
Expand Down Expand Up @@ -247,6 +253,7 @@ exports.Pool = function (factory) {
continue;
}
availableObjects.shift();
inUseObjects.push(objWithTimeout.obj);
clientCb = waitingClients.dequeue();
return clientCb(err, objWithTimeout.obj);
}
Expand Down Expand Up @@ -279,6 +286,7 @@ exports.Pool = function (factory) {
dispense();
});
} else {
inUseObjects.push(obj);
if (clientCb) {
clientCb(err, obj);
} else {
Expand Down Expand Up @@ -334,19 +342,28 @@ exports.Pool = function (factory) {
* The acquired object to be put back to the pool.
*/
me.release = function (obj) {
// check to see if this object has already been released (i.e., is back in the pool of availableObjects)
// check to see if this object has already been released (i.e., is back in the pool of availableObjects)
if (availableObjects.some(function(objWithTimeout) { return (objWithTimeout.obj === obj); })) {
log("release called twice for the same resource: " + (new Error().stack), 'error');
return;
}

// check to see if this object exists in the `in use` list and remove it
var index = inUseObjects.indexOf(obj);
if (index < 0) {
log("attempt to release an invalid resource: " + (new Error().stack), 'error');
return;
}

//log("return to pool");
inUseObjects.splice(index, 1);
var objWithTimeout = { obj: obj, timeout: (new Date().getTime() + idleTimeoutMillis) };
if(returnToHead){
availableObjects.splice(0, 0, objWithTimeout);
availableObjects.splice(0, 0, objWithTimeout);
}
else{
availableObjects.push(objWithTimeout);
}
availableObjects.push(objWithTimeout);
}
log("timeout: " + objWithTimeout.timeout, 'verbose');
dispense();
scheduleRemoveIdle();
Expand Down Expand Up @@ -465,13 +482,17 @@ exports.Pool = function (factory) {
return availableObjects.length;
};

me.inUseObjectsCount = function() {
return inUseObjects.length;
};

me.waitingClientsCount = function() {
return waitingClients.size();
};

me.getMaxPoolSize = function(){
return factory.max;
}
};

// create initial resources (if factory.min > 0)
ensureMinimum();
Expand Down

0 comments on commit 7eef89d

Please sign in to comment.