├── .gitignore ├── History.md ├── Makefile ├── Readme.md ├── component.json ├── index.js ├── package.json └── test └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /History.md: -------------------------------------------------------------------------------- 1 | 2 | v1.1.0 / 2014-11-23 3 | =================== 4 | 5 | * make jitter proportional to backoff duration 6 | 7 | 1.0.1 / 2014-02-17 8 | ================== 9 | 10 | * go away decimal point 11 | * history 12 | 13 | 1.0.0 / 2014-02-17 14 | ================== 15 | 16 | * add jitter option 17 | * Initial commit 18 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | test: 3 | @./node_modules/.bin/mocha \ 4 | --require should \ 5 | --reporter dot \ 6 | --bail 7 | 8 | .PHONY: test -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # backo 2 | 3 | Simple exponential backoff because the others seem to have weird abstractions. 4 | 5 | ## Installation 6 | 7 | ``` 8 | $ npm install backo 9 | ``` 10 | 11 | ## Options 12 | 13 | - `min` initial timeout in milliseconds [100] 14 | - `max` max timeout [10000] 15 | - `jitter` [0] 16 | - `factor` [2] 17 | 18 | ## Example 19 | 20 | ```js 21 | var Backoff = require('backo'); 22 | var backoff = new Backoff({ min: 100, max: 20000 }); 23 | 24 | setTimeout(function(){ 25 | something.reconnect(); 26 | }, backoff.duration()); 27 | 28 | // later when something works 29 | backoff.reset() 30 | ``` 31 | 32 | # License 33 | 34 | MIT 35 | -------------------------------------------------------------------------------- /component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backo", 3 | "repo": "segmentio/backo", 4 | "dependencies": {}, 5 | "version": "1.1.0", 6 | "description": "simple backoff without the weird abstractions", 7 | "keywords": ["backoff"], 8 | "license": "MIT", 9 | "scripts": ["index.js"], 10 | "main": "index.js" 11 | } 12 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Expose `Backoff`. 4 | */ 5 | 6 | module.exports = Backoff; 7 | 8 | /** 9 | * Initialize backoff timer with `opts`. 10 | * 11 | * - `min` initial timeout in milliseconds [100] 12 | * - `max` max timeout [10000] 13 | * - `jitter` [0] 14 | * - `factor` [2] 15 | * 16 | * @param {Object} opts 17 | * @api public 18 | */ 19 | 20 | function Backoff(opts) { 21 | opts = opts || {}; 22 | this.ms = opts.min || 100; 23 | this.max = opts.max || 10000; 24 | this.factor = opts.factor || 2; 25 | this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0; 26 | this.attempts = 0; 27 | } 28 | 29 | /** 30 | * Return the backoff duration. 31 | * 32 | * @return {Number} 33 | * @api public 34 | */ 35 | 36 | Backoff.prototype.duration = function(){ 37 | var ms = this.ms * Math.pow(this.factor, this.attempts++); 38 | if (this.jitter) { 39 | var rand = Math.random(); 40 | var deviation = Math.floor(rand * this.jitter * ms); 41 | ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation; 42 | } 43 | return Math.min(ms, this.max) | 0; 44 | }; 45 | 46 | /** 47 | * Reset the number of attempts. 48 | * 49 | * @api public 50 | */ 51 | 52 | Backoff.prototype.reset = function(){ 53 | this.attempts = 0; 54 | }; 55 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backo", 3 | "version": "1.1.0", 4 | "repository": "segmentio/backo", 5 | "description": "simple backoff without the weird abstractions", 6 | "keywords": [ 7 | "backoff" 8 | ], 9 | "dependencies": {}, 10 | "devDependencies": { 11 | "mocha": "*", 12 | "should": "*" 13 | }, 14 | "license": "MIT" 15 | } -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | 2 | var Backoff = require('..'); 3 | var assert = require('assert'); 4 | 5 | describe('.duration()', function(){ 6 | it('should increase the backoff', function(){ 7 | var b = new Backoff; 8 | 9 | assert(100 == b.duration()); 10 | assert(200 == b.duration()); 11 | assert(400 == b.duration()); 12 | assert(800 == b.duration()); 13 | 14 | b.reset(); 15 | assert(100 == b.duration()); 16 | assert(200 == b.duration()); 17 | }) 18 | }) --------------------------------------------------------------------------------