basant307/AI_Governance_Project
045
1function RetryOperation(timeouts, options) {2 // Compatibility for the old (timeouts, retryForever) signature3 if (typeof options === 'boolean') {4 options = { forever: options };5 }6 7 this._originalTimeouts = JSON.parse(JSON.stringify(timeouts));8 this._timeouts = timeouts;9 this._options = options || {};10 this._maxRetryTime = options && options.maxRetryTime || Infinity;11 this._fn = null;12 this._errors = [];13 this._attempts = 1;14 this._operationTimeout = null;15 this._operationTimeoutCb = null;16 this._timeout = null;17 this._operationStart = null;18 this._timer = null;19 20 if (this._options.forever) {21 this._cachedTimeouts = this._timeouts.slice(0);22 }23}24module.exports = RetryOperation;25 26RetryOperation.prototype.reset = function() {27 this._attempts = 1;28 this._timeouts = this._originalTimeouts.slice(0);29}30 31RetryOperation.prototype.stop = function() {32 if (this._timeout) {33 clearTimeout(this._timeout);34 }35 if (this._timer) {36 clearTimeout(this._timer);37 }38 39 this._timeouts = [];40 this._cachedTimeouts = null;41};42 43RetryOperation.prototype.retry = function(err) {44 if (this._timeout) {45 clearTimeout(this._timeout);46 }47 48 if (!err) {49 return false;50 }51 var currentTime = new Date().getTime();52 if (err && currentTime - this._operationStart >= this._maxRetryTime) {53 this._errors.push(err);54 this._errors.unshift(new Error('RetryOperation timeout occurred'));55 return false;56 }57 58 this._errors.push(err);59 60 var timeout = this._timeouts.shift();61 if (timeout === undefined) {62 if (this._cachedTimeouts) {63 // retry forever, only keep last error64 this._errors.splice(0, this._errors.length - 1);65 timeout = this._cachedTimeouts.slice(-1);66 } else {67 return false;68 }69 }70 71 var self = this;72 this._timer = setTimeout(function() {73 self._attempts++;74 75 if (self._operationTimeoutCb) {76 self._timeout = setTimeout(function() {77 self._operationTimeoutCb(self._attempts);78 }, self._operationTimeout);79 80 if (self._options.unref) {81 self._timeout.unref();82 }83 }84 85 self._fn(self._attempts);86 }, timeout);87 88 if (this._options.unref) {89 this._timer.unref();90 }91 92 return true;93};94 95RetryOperation.prototype.attempt = function(fn, timeoutOps) {96 this._fn = fn;97 98 if (timeoutOps) {99 if (timeoutOps.timeout) {100 this._operationTimeout = timeoutOps.timeout;101 }102 if (timeoutOps.cb) {103 this._operationTimeoutCb = timeoutOps.cb;104 }105 }106 107 var self = this;108 if (this._operationTimeoutCb) {109 this._timeout = setTimeout(function() {110 self._operationTimeoutCb();111 }, self._operationTimeout);112 }113 114 this._operationStart = new Date().getTime();115 116 this._fn(this._attempts);117};118 119RetryOperation.prototype.try = function(fn) {120 console.log('Using RetryOperation.try() is deprecated');121 this.attempt(fn);122};123 124RetryOperation.prototype.start = function(fn) {125 console.log('Using RetryOperation.start() is deprecated');126 this.attempt(fn);127};128 129RetryOperation.prototype.start = RetryOperation.prototype.try;130 131RetryOperation.prototype.errors = function() {132 return this._errors;133};134 135RetryOperation.prototype.attempts = function() {136 return this._attempts;137};138 139RetryOperation.prototype.mainError = function() {140 if (this._errors.length === 0) {141 return null;142 }143 144 var counts = {};145 var mainError = null;146 var mainErrorCount = 0;147 148 for (var i = 0; i < this._errors.length; i++) {149 var error = this._errors[i];150 var message = error.message;151 var count = (counts[message] || 0) + 1;152 153 counts[message] = count;154 155 if (count >= mainErrorCount) {156 mainError = error;157 mainErrorCount = count;158 }159 }160 161 return mainError;162};163 