Name: js-handler/node_modules/restify/node_modules/backoff/README.md
| 1: | # Backoff for Node.js [](http://travis-ci.org/MathieuTurcotte/node-backoff) |
| 2: | |
| 3: | Fibonacci and exponential backoffs for Node.js. |
| 4: | |
| 5: | ## Installation |
| 6: | |
| 7: | ``` |
| 8: | npm install backoff |
| 9: | ``` |
| 10: | |
| 11: | ## Unit tests |
| 12: | |
| 13: | ``` |
| 14: | npm test |
| 15: | ``` |
| 16: | |
| 17: | ## Usage |
| 18: | |
| 19: | ### Object Oriented |
| 20: | |
| 21: | The usual way to instantiate a new `Backoff` object is to use one predefined |
| 22: | factory method: `backoff.fibonacci([options])`, `backoff.exponential([options])`. |
| 23: | |
| 24: | `Backoff` inherits from `EventEmitter`. When a backoff starts, a `backoff` |
| 25: | event is emitted and, when a backoff ends, a `ready` event is emitted. |
| 26: | Handlers for these two events are called with the current backoff number and |
| 27: | delay. |
| 28: | |
| 29: | ``` js |
| 30: | var backoff = require('backoff'); |
| 31: | |
| 32: | var fibonacciBackoff = backoff.fibonacci({ |
| 33: | randomisationFactor: 0, |
| 34: | initialDelay: 10, |
| 35: | maxDelay: 300 |
| 36: | }); |
| 37: | |
| 38: | fibonacciBackoff.failAfter(10); |
| 39: | |
| 40: | fibonacciBackoff.on('backoff', function(number, delay) { |
| 41: | // Do something when backoff starts, e.g. show to the |
| 42: | // user the delay before next reconnection attempt. |
| 43: | console.log(number + ' ' + delay + 'ms'); |
| 44: | }); |
| 45: | |
| 46: | fibonacciBackoff.on('ready', function(number, delay) { |
| 47: | // Do something when backoff ends, e.g. retry a failed |
| 48: | // operation (DNS lookup, API call, etc.). If it fails |
| 49: | // again then backoff, otherwise reset the backoff |
| 50: | // instance. |
| 51: | fibonacciBackoff.backoff(); |
| 52: | }); |
| 53: | |
| 54: | fibonacciBackoff.on('fail', function() { |
| 55: | // Do something when the maximum number of backoffs is |
| 56: | // reached, e.g. ask the user to check its connection. |
| 57: | console.log('fail'); |
| 58: | }); |
| 59: | |
| 60: | fibonacciBackoff.backoff(); |
| 61: | ``` |
| 62: | |
| 63: | The previous example would print the following. |
| 64: | |
| 65: | ``` |
| 66: | 0 10ms |
| 67: | 1 10ms |
| 68: | 2 20ms |
| 69: | 3 30ms |
| 70: | 4 50ms |
| 71: | 5 80ms |
| 72: | 6 130ms |
| 73: | 7 210ms |
| 74: | 8 300ms |
| 75: | 9 300ms |
| 76: | fail |
| 77: | ``` |
| 78: | |
| 79: | Note that `Backoff` objects are meant to be instantiated once and reused |
| 80: | several times by calling `reset` after a successful "retry". |
| 81: | |
| 82: | ### Functional |
| 83: | |
| 84: | It's also possible to avoid some boilerplate code when invoking an asynchronous |
| 85: | function in a backoff loop by using `backoff.call(fn, [args, ...], callback)`. |
| 86: | |
| 87: | Typical usage looks like the following. |
| 88: | |
| 89: | ``` js |
| 90: | var call = backoff.call(get, 'https://duplika.ca/', function(err, res) { |
| 91: | console.log('Retries: ' + call.getResults().length); |
| 92: | |
| 93: | if (err) { |
| 94: | console.log('Error: ' + err.message); |
| 95: | } else { |
| 96: | console.log('Status: ' + res.statusCode); |
| 97: | } |
| 98: | }); |
| 99: | |
| 100: | call.setStrategy(new backoff.ExponentialStrategy()); |
| 101: | call.failAfter(10); |
| 102: | call.start(); |
| 103: | ``` |
| 104: | |
| 105: | ## API |
| 106: | |
| 107: | ### backoff.fibonacci([options]) |
| 108: | |
| 109: | Constructs a Fibonacci backoff (10, 10, 20, 30, 50, etc.). |
| 110: | |
| 111: | See bellow for options description. |
| 112: | |
| 113: | ### backoff.exponential([options]) |
| 114: | |
| 115: | Constructs an exponential backoff (10, 20, 40, 80, etc.). |
| 116: | |
| 117: | The options are the following. |
| 118: | |
| 119: | - randomisationFactor: defaults to 0, must be between 0 and 1 |
| 120: | - initialDelay: defaults to 100 ms |
| 121: | - maxDelay: defaults to 10000 ms |
| 122: | |
| 123: | With these values, the backoff delay will increase from 100 ms to 10000 ms. The |
| 124: | randomisation factor controls the range of randomness and must be between 0 |
| 125: | and 1. By default, no randomisation is applied on the backoff delay. |
| 126: | |
| 127: | ### backoff.call(fn, [args, ...], callback) |
| 128: | |
| 129: | - fn: function to call in a backoff handler, i.e. the wrapped function |
| 130: | - args: function's arguments |
| 131: | - callback: function's callback accepting an error as its first argument |
| 132: | |
| 133: | Constructs a `FunctionCall` instance for the given function. The wrapped |
| 134: | function will get retried until it succeds or reaches the maximum number |
| 135: | of backoffs. In both cases, the callback function will be invoked with the |
| 136: | last result returned by the wrapped function. |
| 137: | |
| 138: | It is the caller's responsability to initiate the call by invoking the |
| 139: | `start` method on the returned `FunctionCall` instance. |
| 140: | |
| 141: | ### Class Backoff |
| 142: | |
| 143: | #### new Backoff(strategy) |
| 144: | |
| 145: | - strategy: the backoff strategy to use |
| 146: | |
| 147: | Constructs a new backoff object from a specific backoff strategy. The backoff |
| 148: | strategy must implement the `BackoffStrategy`interface defined bellow. |
| 149: | |
| 150: | #### backoff.failAfter(numberOfBackoffs) |
| 151: | |
| 152: | - numberOfBackoffs: maximum number of backoffs before the fail event gets |
| 153: | emitted, must be greater than 0 |
| 154: | |
| 155: | Sets a limit on the maximum number of backoffs that can be performed before |
| 156: | a fail event gets emitted and the backoff instance is reset. By default, there |
| 157: | is no limit on the number of backoffs that can be performed. |
| 158: | |
| 159: | #### backoff.backoff([err]) |
| 160: | |
| 161: | Starts a backoff operation. If provided, the error parameter will be emitted |
| 162: | as the last argument of the `backoff` and `fail` events to let the listeners |
| 163: | know why the backoff operation was attempted. |
| 164: | |
| 165: | An error will be thrown an error if a backoff operation is already in progress. |
| 166: | |
| 167: | In practice, this method should be called after a failed attempt to perform a |
| 168: | sensitive operation (connecting to a database, downloading a resource over the |
| 169: | network, etc.). |
| 170: | |
| 171: | #### backoff.reset() |
| 172: | |
| 173: | Resets the backoff delay to the initial backoff delay and stop any backoff |
| 174: | operation in progress. After reset, a backoff instance can and should be |
| 175: | reused. |
| 176: | |
| 177: | In practice, this method should be called after having successfully completed |
| 178: | the sensitive operation guarded by the backoff instance or if the client code |
| 179: | request to stop any reconnection attempt. |
| 180: | |
| 181: | #### Event: 'backoff' |
| 182: | |
| 183: | - number: number of backoffs since last reset, starting at 0 |
| 184: | - delay: backoff delay in milliseconds |
| 185: | - err: optional error parameter passed to `backoff.backoff([err])` |
| 186: | |
| 187: | Emitted when a backoff operation is started. Signals to the client how long |
| 188: | the next backoff delay will be. |
| 189: | |
| 190: | #### Event: 'ready' |
| 191: | |
| 192: | - number: number of backoffs since last reset, starting at 0 |
| 193: | - delay: backoff delay in milliseconds |
| 194: | |
| 195: | Emitted when a backoff operation is done. Signals that the failing operation |
| 196: | should be retried. |
| 197: | |
| 198: | #### Event: 'fail' |
| 199: | |
| 200: | - err: optional error parameter passed to `backoff.backoff([err])` |
| 201: | |
| 202: | Emitted when the maximum number of backoffs is reached. This event will only |
| 203: | be emitted if the client has set a limit on the number of backoffs by calling |
| 204: | `backoff.failAfter(numberOfBackoffs)`. The backoff instance is automatically |
| 205: | reset after this event is emitted. |
| 206: | |
| 207: | ### Interface BackoffStrategy |
| 208: | |
| 209: | A backoff strategy must provide the following methods. |
| 210: | |
| 211: | #### strategy.next() |
| 212: | |
| 213: | Computes and returns the next backoff delay. |
| 214: | |
| 215: | #### strategy.reset() |
| 216: | |
| 217: | Resets the backoff delay to its initial value. |
| 218: | |
| 219: | ### Class ExponentialStrategy |
| 220: | |
| 221: | Exponential (10, 20, 40, 80, etc.) backoff strategy implementation. |
| 222: | |
| 223: | #### new ExponentialStrategy([options]) |
| 224: | |
| 225: | The options are the following. |
| 226: | |
| 227: | - randomisationFactor: defaults to 0, must be between 0 and 1 |
| 228: | - initialDelay: defaults to 100 ms |
| 229: | - maxDelay: defaults to 10000 ms |
| 230: | |
| 231: | ### Class FibonacciStrategy |
| 232: | |
| 233: | Fibonnaci (10, 10, 20, 30, 50, etc.) backoff strategy implementation. |
| 234: | |
| 235: | #### new FibonacciStrategy([options]) |
| 236: | |
| 237: | The options are the following. |
| 238: | |
| 239: | - randomisationFactor: defaults to 0, must be between 0 and 1 |
| 240: | - initialDelay: defaults to 100 ms |
| 241: | - maxDelay: defaults to 10000 ms |
| 242: | |
| 243: | ### Class FunctionCall |
| 244: | |
| 245: | This class manages the calling of an asynchronous function within a backoff |
| 246: | loop. |
| 247: | |
| 248: | This class should rarely be instantiated directly since the factory method |
| 249: | `backoff.call(fn, [args, ...], callback)` offers a more convenient and safer |
| 250: | way to create `FunctionCall` instances. |
| 251: | |
| 252: | #### new FunctionCall(fn, args, callback) |
| 253: | |
| 254: | - fn: asynchronous function to call |
| 255: | - args: an array containing fn's args |
| 256: | - callback: fn's callback |
| 257: | |
| 258: | Constructs a function handler for the given asynchronous function. |
| 259: | |
| 260: | #### call.setStrategy(strategy) |
| 261: | |
| 262: | - strategy: strategy instance to use, defaults to `FibonacciStrategy`. |
| 263: | |
| 264: | Sets the backoff strategy to use. This method should be called before |
| 265: | `call.call()`. |
| 266: | |
| 267: | #### call.failAfter(maxNumberOfBackoffs) |
| 268: | |
| 269: | - maxNumberOfBackoffs: maximum number of backoffs before the call is aborted |
| 270: | |
| 271: | Sets the maximum number of backoffs before the call is aborted. By default, |
| 272: | there is no limit on the number of backoffs that can be performed. |
| 273: | |
| 274: | This method should be called before `call.call()`. |
| 275: | |
| 276: | #### call.getResults() |
| 277: | |
| 278: | Retrieves all intermediary results returned by the wrapped function. This |
| 279: | method can be called at any point in time during the call life cycle, i.e. |
| 280: | before, during and after the wrapped function invocation. |
| 281: | |
| 282: | Returns an array of arrays containing the results returned by the wrapped |
| 283: | function for each call. For example, to get the error code returned by the |
| 284: | second call, one would do the following. |
| 285: | |
| 286: | ``` js |
| 287: | var results = call.getResults(); |
| 288: | var error = results[1][0]; |
| 289: | ``` |
| 290: | |
| 291: | #### call.start() |
| 292: | |
| 293: | Initiates the call the wrapped function. This method should only be called |
| 294: | once per function call instance. |
| 295: | |
| 296: | #### call.abort() |
| 297: | |
| 298: | Aborts the call. |
| 299: | |
| 300: | Past results can be retrieved using `call.getResults()`. This method can be |
| 301: | called at any point in time during the call life cycle, i.e. before, during |
| 302: | and after the wrapped function invocation. |
| 303: | |
| 304: | #### Event: 'call' |
| 305: | |
| 306: | - args: wrapped function's arguments |
| 307: | |
| 308: | Emitted each time the wrapped function is called. |
| 309: | |
| 310: | #### Event: 'callback' |
| 311: | |
| 312: | - results: wrapped function's return values |
| 313: | |
| 314: | Emitted each time the wrapped function invokes its callback. |
| 315: | |
| 316: | #### Event: 'backoff' |
| 317: | |
| 318: | - number: backoff number, starts at 0 |
| 319: | - delay: backoff delay in milliseconds |
| 320: | - err: the error that triggered the backoff operation |
| 321: | |
| 322: | Emitted each time a backoff operation is started. |
| 323: | |
| 324: | ## License |
| 325: | |
| 326: | This code is free to use under the terms of the [MIT license](http://mturcotte.mit-license.org/). |
