Skip to content

Commit

Permalink
Merge branch 'exponential-backoff'
Browse files Browse the repository at this point in the history
  • Loading branch information
orangejulius committed Jul 15, 2015
2 parents 7c51c64 + bc459d2 commit 02388de
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 1 deletion.
47 changes: 47 additions & 0 deletions lib/ExponentialBackoff.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use strict';

/**
* ExponentialBackoff class handles the logic for increasing or decreasing the delay between
* multiple requests. See https://en.wikipedia.org/wiki/Exponential_backoff
*
* @param {number} minimum_backoff the lowest permissible delay between requests. defaults to 50ms
* @param {number} exponent the factor by which to increse or decrease the backoff. defaults to 2
* @param {number} starting_backoff the backoff between the first and second request. defaults to * 50ms
*/
var ExponentialBackoff = function(minimum_backoff, exponent, starting_backoff) {
this.minimum_backoff = minimum_backoff || 50;
this.exponent = exponent || 2.0;
this.starting_backoff = starting_backoff || this.minimum_backoff;

this.backoff = this.starting_backoff;
};

/**
* Get the current backoff as a simple number
*/
ExponentialBackoff.prototype.getBackoff = function getBackoff() {
return this.backoff;
};


/**
* Increase the backoff for the next request. This method should be called after something happens
* that would indicate a slowdown is needed, such as a failed request.
*/
ExponentialBackoff.prototype.increaseBackoff = function increaseBackoff() {
this.backoff *= this.exponent;
};

/**
* Decrease the backoff for the next request. The backoff will never go below the miniumum backoff
* value. This should be called when things are going smoothly, such as after a successful request.
*/
ExponentialBackoff.prototype.decreaseBackoff = function decreaseBackoff() {
if (this.backoff <= this.minimum_backoff) {
this.backoff = this.minimum_backoff;
} else {
this.backoff /= this.exponent;
}
};

module.exports = ExponentialBackoff;
7 changes: 6 additions & 1 deletion lib/run_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ try {
locations = [];
}

var ExponentialBackoff = require( '../lib/ExponentialBackoff');
var util = require( 'util' );
var isObject = require( 'is-object' );
var request = require( 'request' );
Expand Down Expand Up @@ -158,6 +159,7 @@ function execTestSuite( apiUrl, testSuite, cb ){
return;
}

var test_interval = new ExponentialBackoff();
testSuite.tests.forEach( function ( testCase ){
if( validTestStatuses.indexOf( testCase.status ) === -1 ){
throw util.format(
Expand Down Expand Up @@ -204,6 +206,7 @@ function execTestSuite( apiUrl, testSuite, cb ){
return;
}
else if( retry_codes.indexOf(res.statusCode) !== -1 ){
test_interval.increaseBackoff();
testSuite.tests.push( testCase );
return;
}
Expand All @@ -221,6 +224,8 @@ function execTestSuite( apiUrl, testSuite, cb ){
process.exit( 1 );
}

test_interval.decreaseBackoff();

stats.testsCompleted++;
process.stderr.write( util.format(
'\rTests completed: %s/%s', stats.testsCompleted.toString().bold,
Expand Down Expand Up @@ -269,7 +274,7 @@ function execTestSuite( apiUrl, testSuite, cb ){
cb( testResults );
}
});
}, 50);
}, test_interval.getBackoff());
}

var stats = {
Expand Down
33 changes: 33 additions & 0 deletions test/ExponentialBackoff.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

var tape = require( 'tape' );
var ExponentialBackoff = require( '../lib/ExponentialBackoff' );


tape( 'ExponentialBackoff', function(test) {
test.test( 'calling increaseBackoff() makes backoff larger', function(t) {
var eb = new ExponentialBackoff();
var startBackoff = eb.getBackoff();
eb.increaseBackoff();
t.ok(startBackoff < eb.getBackoff(), 'backoff was not higher');
t.end();
});

test.test( 'calling decreaseBackoff() lowers backoff', function(t) {
var eb = new ExponentialBackoff();
eb.increaseBackoff();
var startBackoff = eb.getBackoff();
eb.decreaseBackoff();
t.ok(startBackoff > eb.getBackoff(), 'backoff was not lower');
t.end();
});

test.test( 'calling decreaseBackoff() will not lower backoff below minimum', function(t) {
var eb = new ExponentialBackoff();
var startBackoff = eb.getBackoff();
eb.decreaseBackoff();
t.ok(startBackoff === eb.getBackoff(), 'backoff was not equal');
t.end();
});

test.end();
});
1 change: 1 addition & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
'use strict';

require('./fuzzy-tester');
require('./ExponentialBackoff');

0 comments on commit 02388de

Please sign in to comment.