Skip to content

Commit

Permalink
Merge d7dcca3 into e862b0a
Browse files Browse the repository at this point in the history
  • Loading branch information
NatalieWolfe committed Sep 11, 2016
2 parents e862b0a + d7dcca3 commit b7f0b44
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"rules": {
"semi": ["warn", "always"]
}
}
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
language: node_js
node_js:
- "stable"
- "0.12"
- "4"
- "5"
- "6"

branches:
only:
Expand Down
23 changes: 20 additions & 3 deletions lib/PromisePool.js
Original file line number Diff line number Diff line change
Expand Up @@ -338,10 +338,27 @@ function _dispense() {
var self = this;
++this._count;
_createResource.call(this).then(function(client){
self._waitingClients.dequeue().resolve(client);
var waiter = self._waitingClients.dequeue();
if (waiter) {
waiter.resolve(client);
}
else {
// This acquisition was usurped by another resource becoming free. Just return
// this client to the pool and move on.
self.release(client);
}
}, function(err){
--self._count;
self._waitingClients.dequeue().reject(err);
var waiter = self._waitingClients.dequeue();
if (waiter) {
waiter.reject(err);
}
else {
// This acquisition was usurped by another resource becoming free. Since the
// creation of the resource failed and we don't want to swallow the error, throw
// it here. This will propagate out as an `unhandledRejection` on the process.
throw err;
}
});
}
}
Expand Down Expand Up @@ -445,7 +462,7 @@ PromisePool.prototype.release = function(obj) {
}

self._log('timeout: ' + objWithTimeout.timeout, 'verbose');
}
};

if (this._opts.onRelease) {
Promise.resolve(this._opts.onRelease(obj)).then(function(){
Expand Down
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
"docs-full": "jsdoc2md lib/*.js > docs.md",
"docs-readme": "jsdoc2md --template readme-template.md.hbs lib/*.js > README.md",
"gh-pages": "jsdoc -c jsdoc-conf.json -P ./package.json -R ./README.md -r .",
"lint": "eslint *.js lib tests",
"postpublish": "rm docs.md",
"prepublish": "npm run docs",
"test": "./node_modules/.bin/mocha --recursive tests/unit"
"test": "npm run unit",
"unit": "mocha --recursive tests/unit"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -39,10 +41,11 @@
},
"devDependencies": {
"coveralls": "^2.11.2",
"eslint": "^3.5.0",
"jscoverage": "^0.6.0",
"jsdoc-to-markdown": "^1.1.1",
"mocha": "^2.2.5",
"mocha": "^3.0.2",
"mocha-lcov-reporter": "^1.0.0",
"should": "^8.1.1"
"should": "^11.1.0"
}
}
45 changes: 45 additions & 0 deletions tests/unit/factory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

require('should');

try {
var PromisePool = require('../../lib-cov/PromisePool');
}
catch (err) {
var PromisePool = require('../../lib/PromisePool');
}

describe('PromisePool.Factory', function() {
var pool = null;

beforeEach(function() {
var id = 0;
pool = new PromisePool({
name: 'test-pool',
max: 10,
min: 0,
create: function() { return {id: ++id}; },
destroy: function(obj) {}
});
});

describe('#create', function() {
it('should not error with late-rejected promises', function(done) {
var defer = {};
pool._opts.create = function() {
return new Promise(function(resolve, reject) {
defer.resolve = resolve;
defer.reject = reject;
resolve({});
});
};

pool.acquire(function() {
setTimeout(function() {
defer.reject(new Error('rejection!'));
setTimeout(done, 5);
}, 5);
return Promise.resolve();
});
});
});
});
82 changes: 80 additions & 2 deletions tests/unit/pool.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe('PromisePool', function(){
var smallPool = null;

beforeEach(function(){
var id = 0
var id = 0;
pool = new PromisePool({
name: 'test-pool',
max: 100,
Expand Down Expand Up @@ -158,7 +158,9 @@ describe('PromisePool', function(){
it('should propagate errors of the callback', function(){
return pool.acquire(function(conn){
return Promise.reject('bizbang');
}).catch(function(err){
}).then(function(){
true.should.be.false;
}, function(err){
err.should.eql('bizbang');
});
});
Expand Down Expand Up @@ -196,6 +198,82 @@ describe('PromisePool', function(){
rejected.should.be.true;
});
});

it('should handle being usurped when creating connections (#5)', function(done) {
// https://github.com/NatalieWolfe/node-promise-pool/issues/5
const CREATE_TIME = 30;
var conn = null;
var created = 0;
var defer = {};
var deferred = new Promise(function(resolve, reject) {
defer.resolve = resolve;
defer.reject = reject;
});

// 1) Use a pool with only a single available client.
var pool = new PromisePool({
name: 'pool',
max: 2,
min: 0,
drainCheckIntervalMillis: 10,
create: function() {
return new Promise(function(resolve) {
setTimeout(function() {
++created;
resolve({});
}, CREATE_TIME);
});
},
destroy: function(obj) {}
});

// Watch for unhandled rejections.
var calledDone = false;
function end(err) {
process.removeListener('unhandledRejection', end);
if (!err) {
pool.availableLength.should.equal(2);
}
if (!calledDone) {
calledDone = true;
done(err);
}
}
process.once('unhandledRejection', end);

// 2) Acquire the available connection.
pool.acquire(function(_conn) {
conn = _conn;
created.should.equal(1);

// 3) While that is acquired, acquire another, causing creation of a new connection.
acquireSecond();

// 4) Before new connection is established, release the first one.
return new Promise(function(resolve) {
setTimeout(function() {
resolve();
}, CREATE_TIME / 2);
});
}).then(function() {
return deferred;
}).then(function() { setImmediate(end); }, end);

function acquireSecond() {
pool.acquire(function(_conn) {
conn.should.equal(_conn);
created.should.equal(1);

// 5) Once new connection is created, pool should not error.
return new Promise(function(resolve, reject) {
setTimeout(function() {
created.should.equal(2);
resolve();
}, CREATE_TIME);
});
}).then(defer.resolve, defer.reject);
}
});
});

describe('#release', function(){
Expand Down

0 comments on commit b7f0b44

Please sign in to comment.