You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
1.4 KiB

4 years ago
  1. /**
  2. * Expose `Backoff`.
  3. */
  4. module.exports = Backoff;
  5. /**
  6. * Initialize backoff timer with `opts`.
  7. *
  8. * - `min` initial timeout in milliseconds [100]
  9. * - `max` max timeout [10000]
  10. * - `jitter` [0]
  11. * - `factor` [2]
  12. *
  13. * @param {Object} opts
  14. * @api public
  15. */
  16. function Backoff(opts) {
  17. opts = opts || {};
  18. this.ms = opts.min || 100;
  19. this.max = opts.max || 10000;
  20. this.factor = opts.factor || 2;
  21. this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;
  22. this.attempts = 0;
  23. }
  24. /**
  25. * Return the backoff duration.
  26. *
  27. * @return {Number}
  28. * @api public
  29. */
  30. Backoff.prototype.duration = function(){
  31. var ms = this.ms * Math.pow(this.factor, this.attempts++);
  32. if (this.jitter) {
  33. var rand = Math.random();
  34. var deviation = Math.floor(rand * this.jitter * ms);
  35. ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation;
  36. }
  37. return Math.min(ms, this.max) | 0;
  38. };
  39. /**
  40. * Reset the number of attempts.
  41. *
  42. * @api public
  43. */
  44. Backoff.prototype.reset = function(){
  45. this.attempts = 0;
  46. };
  47. /**
  48. * Set the minimum duration
  49. *
  50. * @api public
  51. */
  52. Backoff.prototype.setMin = function(min){
  53. this.ms = min;
  54. };
  55. /**
  56. * Set the maximum duration
  57. *
  58. * @api public
  59. */
  60. Backoff.prototype.setMax = function(max){
  61. this.max = max;
  62. };
  63. /**
  64. * Set the jitter
  65. *
  66. * @api public
  67. */
  68. Backoff.prototype.setJitter = function(jitter){
  69. this.jitter = jitter;
  70. };