Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add a "pooled" function-decorator along with tests

  • Loading branch information...
commit 6fdd2a63479765a32b469f197eb2f8e600234510 1 parent 1ed52d3
@cosbynator cosbynator authored
Showing with 148 additions and 0 deletions.
  1. +39 −0 lib/generic-pool.js
  2. +109 −0 test/generic-pool.test.js
View
39 lib/generic-pool.js
@@ -348,6 +348,44 @@ exports.Pool = function (factory) {
}
};
+ /**
+ * Decorates a function to use a acquired client from the object pool when called.
+ *
+ * @param {Function} decorated
+ * The decorated function, accepting a client as the first argument and
+ * (optionally) a callback as the final argument.
+ *
+ * @param {Number} priority
+ * Optional. Integer between 0 and (priorityRange - 1). Specifies the priority
+ * of the caller if there are no available resources. Lower numbers mean higher
+ * priority.
+ */
+ me.pooled = function(decorated, priority) {
+ return function() {
+ var callerArgs = arguments;
+ var callerCallback = callerArgs[callerArgs.length - 1];
+ var hasCallback = typeof callerCallback === 'function';
+ me.acquire(function(err, client) {
+ if(err) {
+ if(hasCallback) {
+ callerCallback(err);
+ }
+ return;
+ }
+
+ var args = [client].concat(Array.prototype.slice.call(callerArgs, 0, hasCallback ? -1 : undefined));
+ args.push(function() {
+ me.release(client);
+ if(hasCallback) {
+ callerCallback.apply(null, arguments);
+ }
+ });
+
+ decorated.apply(null, args);
+ }, priority);
+ };
+ };
+
me.getPoolSize = function() {
return count;
};
@@ -364,5 +402,6 @@ exports.Pool = function (factory) {
return waitingClients.size();
};
+
return me;
};
View
109 test/generic-pool.test.js
@@ -195,6 +195,115 @@ module.exports = {
});
},
+ 'pooled decorator should acquire and release' : function (beforeExit) {
+ var assertion_count = 0;
+ var destroyed_count = 0;
+ var pool = poolModule.Pool({
+ name : 'test1',
+ create : function(callback) { callback({id: Math.floor(Math.random()*1000)}); },
+ destroy : function(client) { destroyed_count += 1; },
+ max : 1,
+ idleTimeoutMillis : 100
+ });
+
+ var pooledFn = pool.pooled(function(client, cb) {
+ assert.equal(typeof client.id, 'number');
+ assert.equal(pool.getPoolSize(), 1);
+ assertion_count += 2;
+ cb();
+ });
+
+ assert.equal(pool.getPoolSize(), 0);
+ assertion_count += 1;
+
+ pooledFn(function(err) {
+ if (err) { throw err; }
+ assert.ok(true);
+ assertion_count += 1;
+ });
+
+ beforeExit(function() {
+ assert.equal(assertion_count, 4);
+ assert.equal(destroyed_count, 1);
+ });
+ },
+
+ 'pooled decorator should pass arguments and return values' : function(beforeExit) {
+ var assertion_count = 0;
+ var pool = poolModule.Pool({
+ name : 'test1',
+ create : function(callback) { callback({id: Math.floor(Math.random()*1000)}); },
+ destroy : function(client) { },
+ max : 1,
+ idleTimeoutMillis : 100
+ });
+
+ var pooledFn = pool.pooled(function(client, arg1, arg2, cb) {
+ assert.equal(arg1, "First argument");
+ assert.equal(arg2, "Second argument");
+ assertion_count += 2;
+ cb(null, "First return", "Second return");
+ });
+
+ pooledFn("First argument", "Second argument", function(err, retVal1, retVal2) {
+ if(err) { throw err; }
+ assert.equal(retVal1, "First return");
+ assert.equal(retVal2, "Second return");
+ assertion_count += 2;
+ });
+
+ beforeExit(function() {
+ assert.equal(assertion_count, 4);
+ });
+ },
+
+ 'pooled decorator should allow undefined callback' : function(beforeExit) {
+ var assertion_count = 0;
+ var pool = poolModule.Pool({
+ name : 'test1',
+ create : function(callback) { callback({id: Math.floor(Math.random()*1000)}); },
+ destroy : function(client) { },
+ max : 1,
+ idleTimeoutMillis : 100
+ });
+
+ var pooledFn = pool.pooled(function(client, arg) {
+ assert.equal(arg, "Arg!");
+ assertion_count += 1;
+ });
+
+ pooledFn("Arg!");
+
+ beforeExit(function() {
+ assert.equal(assertion_count, 1);
+ });
+
+ },
+
+ 'pooled decorator should forward pool errors' : function(beforeExit) {
+ var assertion_count = 0;
+ var pool = poolModule.Pool({
+ name : 'test1',
+ create : function(callback) { callback(new Error('Pool error')); },
+ destroy : function(client) { },
+ max : 1,
+ idleTimeoutMillis : 100
+ });
+
+ var pooledFn = pool.pooled(function(cb) {
+ assert.ok(false, "Pooled function shouldn't be called due to a pool error");
+ });
+
+ pooledFn(function(err, obj) {
+ assert.equal(err.message, 'Pool error');
+ assertion_count += 1;
+ });
+
+ beforeExit(function() {
+ assert.equal(assertion_count, 1);
+ });
+ },
+
'getPoolSize' : function (beforeExit) {
var assertion_count = 0;
var pool = poolModule.Pool({
Please sign in to comment.
Something went wrong with that request. Please try again.