Backoff.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports["default"] = void 0;
  6. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  7. function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  8. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
  9. var Backoff = /*#__PURE__*/function () {
  10. /**
  11. * Create a backoff instance can automatically backoff retries.
  12. */
  13. function Backoff() {
  14. var min = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 500;
  15. var max = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
  16. var jitter = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
  17. _classCallCheck(this, Backoff);
  18. this._fails = 0;
  19. if (min <= 0) {
  20. throw Error("Backoff min value must be greater than zero or backoff will never back-off.");
  21. }
  22. this.min = min;
  23. this.max = max != null ? max : min * 10;
  24. this.jitter = jitter;
  25. this._current = min;
  26. }
  27. /**
  28. * Return the number of failures.
  29. */
  30. _createClass(Backoff, [{
  31. key: "succeed",
  32. /**
  33. * Clear any pending callbacks and reset the backoff.
  34. */
  35. value: function succeed() {
  36. this.cancel();
  37. this._fails = 0;
  38. this._current = this.min;
  39. }
  40. /**
  41. * Incremet the backoff and schedule a callback if provided.
  42. */
  43. }, {
  44. key: "fail",
  45. value: function fail(callback) {
  46. var _this = this;
  47. this._fails += 1;
  48. var delay = this._current * 2;
  49. if (this.jitter) {
  50. delay *= Math.random();
  51. }
  52. this._current = Math.min(this._current + delay, this.max);
  53. if (callback != null) {
  54. if (this._timeoutId != null) {
  55. if (this._callback !== callback) {
  56. throw new Error('callback already pending');
  57. } else {
  58. // If the callback is the same, just cancel it and re-schedule.
  59. this.cancel();
  60. }
  61. }
  62. this._callback = callback;
  63. this._timeoutId = setTimeout(function () {
  64. try {
  65. if (callback != null) {
  66. callback();
  67. }
  68. } finally {
  69. _this.cancel();
  70. }
  71. }, this._current);
  72. }
  73. return this._current;
  74. }
  75. /**
  76. * Clear any pending callbacks.
  77. */
  78. }, {
  79. key: "cancel",
  80. value: function cancel() {
  81. this._callback = null;
  82. if (this._timeoutId != null) {
  83. clearTimeout(this._timeoutId);
  84. this._timeoutId = null;
  85. }
  86. }
  87. }, {
  88. key: "fails",
  89. get: function get() {
  90. return this._fails;
  91. }
  92. /**
  93. * Current backoff value in milliseconds.
  94. */
  95. }, {
  96. key: "current",
  97. get: function get() {
  98. return this._current;
  99. }
  100. /**
  101. * A callback is going to fire.
  102. */
  103. }, {
  104. key: "pending",
  105. get: function get() {
  106. return this._timeoutId != null;
  107. }
  108. }]);
  109. return Backoff;
  110. }();
  111. exports["default"] = Backoff;
  112. module.exports = exports.default;