Skip to content

Commit

Permalink
fix: eliminates a bug where the circuit could remain halfOpen forever
Browse files Browse the repository at this point in the history
Fixes: #276
  • Loading branch information
lance committed Feb 22, 2019
1 parent 95a4946 commit 0039ee1
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/circuit.js
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ function fail (circuit, err, args, latency) {

// check stats to see if the circuit should be opened
const stats = circuit.stats;
if (stats.fires < circuit.volumeThreshold) return;
if ((stats.fires < circuit.volumeThreshold) && !circuit.halfOpen) return;
const errorRate = stats.failures / stats.fires * 100;
if (errorRate > circuit.options.errorThresholdPercentage ||
stats.failures >= circuit.options.maxFailures ||
Expand Down
36 changes: 36 additions & 0 deletions test/volume-threshold-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,39 @@ test('Has a volume threshold before tripping when option is provided', t => {
});
});
});

// TODO: This test is a little flakey and depends on the machine
// where the test is running to be reasonably fast due to timeouts
test('volume threshold does not affect halfOpen state', t => {
t.plan(5);
const options = {
errorThresholdPercentage: 1,
resetTimeout: 300,
rollingCountTimeout: 300,
volumeThreshold: 2
};

const breaker = opossum(passFail, options);
breaker.fire(-1)
.then(t.fail)
.catch(_ => {
t.ok(breaker.closed, 'breaker should still be open after one failure');
breaker.fire(-1)
.then(t.fail)
.catch(e => {
t.ok(breaker.opened, 'breaker should be open');
}).then(_ => {
setTimeout(_ => { // ensure that we have entered the halfOpen state
t.ok(breaker.halfOpen, 'breaker should be in halfOpen state');
t.ok(breaker.stats.fires === 0, 'statistical window should be cleared');
// now fail again and ensure that we reenter the open state
breaker.fire(-1)
.then(t.fail)
.catch(_ => {
t.ok(breaker.opened, 'breaker should be in the open state');
})
.then(_ => t.end());
}, options.resetTimeout * 1.5);
});
});
});

0 comments on commit 0039ee1

Please sign in to comment.