Permalink
Browse files

Added #pull, fault tolerant allocations with retry.

  • Loading branch information...
3rd-Eden committed Jun 24, 2012
1 parent ff1a7da commit 5fe8b979e5ed37f5fad24d1367e08c0661bea0cf
Showing with 71 additions and 2 deletions.
  1. +39 −1 lib/connectionpool.js
  2. +3 −1 package.json
  3. +29 −0 test/connectionpool.test.js
View
@@ -1,6 +1,7 @@
'use strict';
-var EventEmitter = require('events').EventEmitter;
+var EventEmitter = require('events').EventEmitter
+ , retry = require('retry');
/**
* A net.Stream connection pool.
@@ -15,6 +16,7 @@ function Manager(limit, builder) {
this.limit = +limit || 20; // defaults to 20 connections max
this.pool = [];
this.generator = null;
+ this.retries = 5;
// some stats that can be used for metrics
this.metrics = {
@@ -79,6 +81,41 @@ Manager.prototype.listen = function listen(net) {
.on('end', regenerate);
};
+/**
+ * A fault tolerant connection allocation wrapper.
+ *
+ * @param {Function} fn
+ * @api private
+ */
+
+Manager.prototype.pull = function pull(fn) {
+ var operation = retry.operation({
+ retries: this.retries
+ , factor: 3
+ , minTimeout: 1 * 1000
+ , maxTimeout: 60 * 1000
+ , randomize: true
+ })
+ , self = this;
+
+ /**
+ * Small wrapper around pulling a connection
+ *
+ * @param {Error} err
+ * @api private
+ */
+
+ function allocate(err) {
+ if (operation.retry(err)) return;
+
+ fn.apply(fn, arguments);
+ }
+
+ operation.attempt(function attempt() {
+ self.allocate(allocate);
+ });
+};
+
/**
* Allocate a new connection from the connection pool, this can be done async
* that's why we use a error first callback pattern.
@@ -278,6 +315,7 @@ Manager.prototype.free = function free(keep) {
*/
Manager.prototype.end = function end() {
+ this.emit('end');
return this.free(0);
};
View
@@ -14,7 +14,9 @@
"engines": {
"node": "~0.6.0"
},
- "dependencies": {},
+ "dependencies": {
+ "retry": "0.6.0"
+ },
"devDependencies": {
"mocha": "1.2.0",
"chai": "1.0.4"
@@ -165,6 +165,35 @@ describe('connectionpool', function () {
connection.end();
});
});
+
+ it('should handle burst allocations', function (done) {
+ var pool = new ConnectionPool()
+ , count = 0
+ , allocations = 25;
+
+ pool.factory(function factory() {
+ return net.connect(port, host);
+ });
+
+ /**
+ * Small helper function.
+ *
+ * @param {error} err
+ * @api private
+ */
+
+ function allocate(err) {
+ if (++count !== allocations) return;
+ expect(pool.pool).to.have.length(pool.limit);
+
+ pool.free(0);
+ done();
+ }
+
+ for (var i = 0; i < allocations; i++) {
+ pool.allocate(allocate);
+ }
+ });
});
describe('#free', function () {

0 comments on commit 5fe8b97

Please sign in to comment.