@creejs/commons-retrier 2.1.16 → 2.1.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index-dev.cjs +305 -123
- package/dist/cjs/index-dev.cjs.map +1 -1
- package/dist/cjs/index-min.cjs +1 -1
- package/dist/cjs/index-min.cjs.map +1 -1
- package/dist/esm/index-dev.js +305 -123
- package/dist/esm/index-dev.js.map +1 -1
- package/dist/esm/index-min.js +1 -1
- package/dist/esm/index-min.js.map +1 -1
- package/dist/umd/index.dev.js +305 -123
- package/dist/umd/index.dev.js.map +1 -1
- package/dist/umd/index.min.js +1 -1
- package/dist/umd/index.min.js.map +1 -1
- package/package.json +3 -3
- package/types/forever-task.d.ts +35 -0
- package/types/policy/fixed-interval-policy.d.ts +7 -1
- package/types/retrier.d.ts +30 -5
package/dist/cjs/index-dev.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
let
|
|
5
|
+
let e$1 = class e extends Error{static isAggregatedErrorLike(t){return t&&Array.isArray(t.errors)}static isAggregatedError(t){return t instanceof e}constructor(t,r){super(t),this.errors=r??[];}addError(t){this.errors.push(t);}removeError(t){const r=this.errors.indexOf(t);return -1!==r&&(this.errors.splice(r,1),true)}};var n$1={constructorName:o$1,defaults:function(t,...r){if(null==t)throw new TypeError('"target" Should Not Nil');for(const e of r)if(null!=e)for(const r in e) void 0===t[r]&&(t[r]=e[r]);return t},extend:i$1,extends:i$1,equals:function(t,r){if(t===r)return true;if("function"==typeof t?.equals)return t.equals(r);if("function"==typeof r?.equals)return r.equals(t);return false},isBrowser:s$1,isNode:function(){return !s$1()},cloneToPlainObject:function(t){if(null==t)return t;if("object"!=typeof t)throw new Error("Only Object allowed to clone");return {...t}},deepCloneToPlainObject:function(t){if(null==t)return t;if("object"!=typeof t)throw new Error("Only Object allowed to clone");return JSON.parse(JSON.stringify(t))}};function o$1(t){return t?.constructor?.name}function i$1(t,...r){if(null==t)throw new TypeError('"target" must not be null or undefined');for(const e of r)if(null!=e)for(const r in e)t[r]=e[r];return t}function s$1(){return "undefined"!=typeof window&&"undefined"!=typeof document}var u$1={isArray:f$1,isBoolean:a$1,isBuffer:function(t){return null!=t&&Buffer.isBuffer(t)},isFunction:c$1,isInstance:l$1,isIterable:function(t){return null!=t&&"function"==typeof t[Symbol.iterator]},isDate:function(t){return null!=t&&t instanceof Date},isError:function(t){return null!=t&&t instanceof Error},isMap:function(t){return null!=t&&"object"==typeof t&&t.constructor===Map},isWeakMap:function(t){return null!=t&&"object"==typeof t&&t.constructor===WeakMap},isNumber:m$1,isPositive:p$1,isNegative:g$1,isNotNegative:h$1,isNil:y,isNullOrUndefined:function(t){return null==t},isNull:w$1,isUndefined:d$1,isPlainObject:A,isObject:b$1,isPromise:E,isRegExp:function(t){return null!=t&&"object"==typeof t&&t.constructor===RegExp},isSet:function(t){return null!=t&&"object"==typeof t&&t.constructor===Set},isWeakSet:function(t){return null!=t&&"object"==typeof t&&t.constructor===WeakSet},isStream:function(t){return null!=t&&"function"==typeof t.pipe},isString:N,isSymbol:$,isPrimitive:function(t){return null!==t&&("string"==typeof t||"number"==typeof t||"boolean"==typeof t)},isInt8Array:O$1,isUint8Array:j,isUint8ClampedArray:P,isInt16Array:S,isUint16Array:x,isInt32Array:U,isUint32Array:T,isFloat32Array:I,isFloat64Array:B,isBigInt64Array:k$1,isBigUint64Array:L$1,isTypedArray:v$1,isArrayBuffer:F};function f$1(t){return Array.isArray(t)}function a$1(t){return "boolean"==typeof t}function c$1(t){return "function"==typeof t}function l$1(t){return null!=t&&"object"==typeof t&&!A(t)}function y(t){return null==t}function p$1(t){return !!m$1(t)&&t>0}function h$1(t){return !!m$1(t)&&t>=0}function g$1(t){return !!m$1(t)&&t<0}function w$1(t){return null===t}function d$1(t){return void 0===t}function m$1(t){return null!=t&&"number"==typeof t}function b$1(t){return null!=t&&"object"==typeof t}function A(t){return null!==t&&"object"==typeof t&&(t.constructor===Object||void 0===t.constructor)}function E(t){return null!=t&&"function"==typeof t.then}function N(t){return null!=t&&"string"==typeof t}function $(t){return null!=t&&"symbol"==typeof t}function v$1(t){return ArrayBuffer.isView(t)&&t.constructor!==DataView}function O$1(t){return t instanceof Int8Array}function j(t){return t instanceof Uint8Array}function P(t){return t instanceof Uint8ClampedArray}function S(t){return t instanceof Int16Array}function x(t){return t instanceof Uint16Array}function U(t){return t instanceof Int32Array}function T(t){return t instanceof Uint32Array}function I(t){return t instanceof Float32Array}function B(t){return t instanceof Float64Array}function k$1(t){return t instanceof BigInt64Array}function L$1(t){return t instanceof BigUint64Array}function F(t){return t instanceof ArrayBuffer}var C={assertNumber:q,assertPositive:_$1,assertNotNegative:J,assertFunction:W,assertNotNil:V,assertString:M};function D(t,r){if(!Array.isArray(t))throw new Error(`${r?'"'+r+'" ':""}Not Array: type=${typeof t} value=${Z(t)}`)}function M(t,r){if(!N(t))throw new Error(`${r?'"'+r+'" ':""}Not String: type=${typeof t} value=${Z(t)}`)}function q(t,r){if(!m$1(t))throw new Error(`${r?'"'+r+'" ':""}Not Number: type=${typeof t} value=${Z(t)}`)}function _$1(t,r){if(!p$1(t))throw new Error(`${r?'"'+r+'" ':""}Not Positive: ${t}`)}function J(t,r){if(!h$1(t))throw new Error(`${r?'"'+r+'" ':""}Not "0 or Positive": ${t}`)}function W(t,r){if(!c$1(t))throw new Error(`${r?'"'+r+'" ':""}Not Function: type=${typeof t} value=${Z(t)}`)}function H(t,r){if(!E(t))throw new Error(`${r?'"'+r+'" ':""}Not Promise: type=${typeof t} value=${Z(t)}`)}function V(t,r){if(y(t))throw new Error((r?'"'+r+'" ':"")+"Should Not Nil")}function Z(t){if(null===t)return "null";if(void 0===t)return "undefined";let r;try{r=JSON.stringify(t);}catch(e){r=t.toString();}return r}var rt={any:function(t){if(D(t),0===t.length)throw new Error("Empty Tasks");const r=et(),n=[];for(let o=0;o<t.length;o++){const i=t[o];let s;if(u$1.isPromise(i))s=i;else {if(!u$1.isFunction(i)){n.push(new Error(`Invalid Task at index ${o}/${t.length-1}: ${i}`));continue}s=ot(i);}s.then(t=>{r.resolve(t);}).catch(o=>{n.push(o),n.length>=t.length&&r.reject(new e$1("All Tasks Failed",n));});}n.length===t.length&&r.reject(new e$1("All Tasks Failed",n));return r.promise},defer:et,delay:function(t,r){u$1.isNumber(t)?(r=t,t=Promise.resolve()):null==t&&null==r&&(r=1,t=Promise.resolve());null!=t&&H(t),q(r=r??1e3);const e=et(),n=Date.now();return t.then((...t)=>{const o=Date.now()-n;o<r?setTimeout(()=>e.resolve(...t),r-o):e.resolve(...t);}).catch(t=>{const o=Date.now()-n;o<r?setTimeout(()=>e.reject(t),r-o):e.reject(t);}),e.promise},timeout:function(t,r,e){H(t),q(r=r??1);const n=et(r,e),o=Date.now();return t.then((...t)=>{Date.now()-o<=r?n.resolve(...t):n.reject(new Error(e??`Promise Timeout: ${r}ms`));}).catch(t=>{!n.resolved&&!n.rejected&&n.reject(t);}),n.promise},allSettled:nt,returnValuePromised:ot,series:async function(t){D(t);const r=[];for(const e of t)if(W(e),u$1.isFunction(e))r.push(await ot(e));else {if(!u$1.isPromise(e))throw new Error(`Invalid Task: ${e}`);r.push(await e);}return r},seriesAllSettled:async function(t){D(t);const r=[];for(const e of t){W(e);try{r.push({ok:!0,result:await e()});}catch(t){r.push({ok:false,result:t});}}return r},parallel:async function(t,r=5){if(D(t),q(r),r<=0)throw new Error(`Invalid maxParallel: ${r}, should > 0`);t.forEach(t=>W(t));const e=[];if(t.length<=r){const r=await Promise.all(t.map(t=>ot(t)));return e.push(...r),e}const n=[];for(const o of t)if(W(o),n.push(o),n.length>=r){const t=await Promise.all(n.map(t=>ot(t)));e.push(...t),n.length=0;}if(n.length>0&&n.length<r){const t=await Promise.all(n.map(t=>ot(t)));e.push(...t);}return e},parallelAny:async function(t,r=5){if(D(t,"tasks"),q(r),0===t.length)throw new Error("Empty Tasks");if(r<=0)throw new Error(`Invalid maxParallel: ${r}, should > 0`);const n=[];let o=0,i=0;const s=et();function f(){if(o>=t.length)return;if(i>r)return;const a=t[o++];let c;if(i++,u$1.isPromise(a))c=a;else {if(!u$1.isFunction(a))return n.push(new TypeError(`Invalid task: ${a}`)),void f();c=ot(a);}c.then(t=>{s.resolve(t);}).catch(r=>{n.push(r),n.length>=t.length&&s.pending?s.reject(new e$1("All Tasks Failed",n)):f();}).finally(()=>{i--;});}for(;i<r;)f();return s.promise},parallelAllSettled:async function(t,r=5){if(D(t),q(r),r<=0)throw new Error(`Invalid maxParallel: ${r}, should > 0`);t.forEach(t=>W(t));const e=[];if(t.length<=r){const r=await nt(t.map(t=>ot(t)));return e.push(...r),e}const n=[];for(const o of t)if(n.push(o),n.length>=r){const t=await nt(n.map(t=>ot(t)));e.push(...t),n.length=0;}if(n.length>0&&n.length<r){const t=await nt(n.map(t=>ot(t)));e.push(...t);}return e},wait:function(t){J(t);const r={};let e;return r.timerHandler=e=setTimeout(()=>{clearTimeout(e),r._resolve();},t),r.promise=new Promise((t,n)=>{r._resolve=r=>{null!=e&&clearTimeout(e),t(r);};}),r.wakeup=()=>{r._resolve();},r}};function et(t=-1,r){q(t);const e={};let n;return e.pending=true,e.canceled=false,e.rejected=false,e.resolved=false,t>=0&&(e.timerCleared=false,e.timerHandler=n=setTimeout(()=>{clearTimeout(n),e.timerCleared=true,e.reject(new Error(r??`Promise Timeout: ${t}ms`));},t)),e.promise=new Promise((t,r)=>{e.resolve=r=>{e.resolved||e.rejected||e.canceled||(null!=n&&(clearTimeout(n),e.timerCleared=true),e.pending=false,e.canceled=false,e.rejected=false,e.resolved=true,t(r));},e.reject=t=>{e.resolved||e.rejected||e.canceled||(null!=n&&(clearTimeout(n),e.timerCleared=true),e.pending=false,e.canceled=false,e.resolved=false,e.rejected=true,r(t));};}),e.cancel=e.promise.cancel=t=>{e.resolved||e.rejected||e.canceled||(null!=n&&(clearTimeout(n),e.timerCleared=true),e.reject(t??new Error("Cancelled")),e.canceled=e.promise.canceled=true);},e}async function nt(t){D(t);const r=await Promise.allSettled(t),e=[];for(const t of r)"fulfilled"===t.status&&e.push({ok:true,result:t.value}),"rejected"===t.status&&e.push({ok:false,result:t.reason});return e}function ot(t){try{const r=t();return u$1.isPromise(r)?r:Promise.resolve(r)}catch(t){return Promise.reject(t)}}new TextDecoder;new TextEncoder;
|
|
6
6
|
|
|
7
7
|
// module vars
|
|
8
8
|
const DefaultMinInterval = 50;
|
|
@@ -12,8 +12,8 @@ const DefaultMaxRetries = 3;
|
|
|
12
12
|
// internal
|
|
13
13
|
|
|
14
14
|
// module vars
|
|
15
|
-
const { assertPositive: assertPositive$5, assertNotNegative: assertNotNegative$3 } =
|
|
16
|
-
const { isNumber } =
|
|
15
|
+
const { assertPositive: assertPositive$5, assertNotNegative: assertNotNegative$3 } = C;
|
|
16
|
+
const { isNumber } = u$1;
|
|
17
17
|
|
|
18
18
|
class Policy {
|
|
19
19
|
/**
|
|
@@ -181,7 +181,7 @@ var Event = {
|
|
|
181
181
|
// 3rd
|
|
182
182
|
// internal
|
|
183
183
|
// module vars
|
|
184
|
-
const { assertPositive: assertPositive$4 } =
|
|
184
|
+
const { assertPositive: assertPositive$4 } = C;
|
|
185
185
|
class FixedIntervalPolicy extends Policy {
|
|
186
186
|
/**
|
|
187
187
|
* Creates a fixed interval retry policy with the specified interval.
|
|
@@ -189,16 +189,25 @@ class FixedIntervalPolicy extends Policy {
|
|
|
189
189
|
*/
|
|
190
190
|
constructor (interval) {
|
|
191
191
|
super();
|
|
192
|
-
|
|
193
|
-
this._interval = interval;
|
|
192
|
+
this.interval = interval;
|
|
194
193
|
}
|
|
195
194
|
|
|
195
|
+
/**
|
|
196
|
+
* @param {number} interval - The fixed interval (in milliseconds) between retry attempts.
|
|
197
|
+
*/
|
|
196
198
|
set interval (interval) {
|
|
197
199
|
assertPositive$4(interval, 'interval');
|
|
198
200
|
this._interval = interval;
|
|
201
|
+
this._nextInterval = interval;
|
|
202
|
+
this._min = interval;
|
|
203
|
+
this._max = interval;
|
|
199
204
|
}
|
|
200
205
|
|
|
206
|
+
/**
|
|
207
|
+
* @returns {number}
|
|
208
|
+
*/
|
|
201
209
|
get interval () {
|
|
210
|
+
// @ts-ignore not possible be undefined
|
|
202
211
|
return this._interval
|
|
203
212
|
}
|
|
204
213
|
|
|
@@ -216,7 +225,7 @@ class FixedIntervalPolicy extends Policy {
|
|
|
216
225
|
// 3rd
|
|
217
226
|
// internal
|
|
218
227
|
// module vars
|
|
219
|
-
const { assertPositive: assertPositive$3 } =
|
|
228
|
+
const { assertPositive: assertPositive$3 } = C;
|
|
220
229
|
class FixedIncreasePolicy extends Policy {
|
|
221
230
|
/**
|
|
222
231
|
* each call to _next() increases the interval by "increasement".
|
|
@@ -253,7 +262,7 @@ class FixedIncreasePolicy extends Policy {
|
|
|
253
262
|
// 3rd
|
|
254
263
|
// internal
|
|
255
264
|
// module vars
|
|
256
|
-
const { assertPositive: assertPositive$2 } =
|
|
265
|
+
const { assertPositive: assertPositive$2 } = C;
|
|
257
266
|
|
|
258
267
|
class FactoreIncreasePolicy extends Policy {
|
|
259
268
|
/**
|
|
@@ -297,7 +306,7 @@ class FactoreIncreasePolicy extends Policy {
|
|
|
297
306
|
// 3rd
|
|
298
307
|
// internal
|
|
299
308
|
// module vars
|
|
300
|
-
const { assertPositive: assertPositive$1 } =
|
|
309
|
+
const { assertPositive: assertPositive$1 } = C;
|
|
301
310
|
|
|
302
311
|
class ShuttlePolicy extends Policy {
|
|
303
312
|
/**
|
|
@@ -342,7 +351,7 @@ class ShuttlePolicy extends Policy {
|
|
|
342
351
|
|
|
343
352
|
// internal
|
|
344
353
|
// module vars
|
|
345
|
-
const { assertNotNegative: assertNotNegative$2 } =
|
|
354
|
+
const { assertNotNegative: assertNotNegative$2 } = C;
|
|
346
355
|
/**
|
|
347
356
|
* @class FixedBackoff
|
|
348
357
|
*/
|
|
@@ -362,7 +371,7 @@ class FixedBackoff extends FixedIntervalPolicy {
|
|
|
362
371
|
// internal
|
|
363
372
|
|
|
364
373
|
// module vars
|
|
365
|
-
const { assertNotNegative: assertNotNegative$1 } =
|
|
374
|
+
const { assertNotNegative: assertNotNegative$1 } = C;
|
|
366
375
|
/**
|
|
367
376
|
* @class ExponentialBackoffPolicy
|
|
368
377
|
*/
|
|
@@ -380,7 +389,7 @@ class ExponentialBackoffPolicy extends FactoreIncreasePolicy {
|
|
|
380
389
|
|
|
381
390
|
// internal
|
|
382
391
|
// module vars
|
|
383
|
-
const { assertNotNegative } =
|
|
392
|
+
const { assertNotNegative } = C;
|
|
384
393
|
/**
|
|
385
394
|
* @class LinearBackoff
|
|
386
395
|
*/
|
|
@@ -404,7 +413,7 @@ class LinearBackoff extends FixedIncreasePolicy {
|
|
|
404
413
|
*/
|
|
405
414
|
|
|
406
415
|
// module vars
|
|
407
|
-
const { assertNotNil, assertFunction: assertFunction$1 } =
|
|
416
|
+
const { assertNotNil, assertFunction: assertFunction$1 } = C;
|
|
408
417
|
class Task {
|
|
409
418
|
/**
|
|
410
419
|
* Creates a new Task instance.
|
|
@@ -496,6 +505,53 @@ class AlwaysTask extends Task {
|
|
|
496
505
|
}
|
|
497
506
|
}
|
|
498
507
|
|
|
508
|
+
// owned
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* @typedef {import('./retrier.js').default} Retrier
|
|
512
|
+
*/
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* The task will execute forever despite of failure or success.
|
|
516
|
+
* 1. Ignore Retrier total timeout setting
|
|
517
|
+
* 2. Ignore Retrier max retries setting
|
|
518
|
+
*/
|
|
519
|
+
class ForeverTask extends Task {
|
|
520
|
+
/**
|
|
521
|
+
* Checks if the given task is an instance of ForeverTask.
|
|
522
|
+
* @param {*} task - The task to check.
|
|
523
|
+
* @returns {boolean} True if the task is an instance of ForeverTask, false otherwise.
|
|
524
|
+
*/
|
|
525
|
+
static isForeverTask (task) {
|
|
526
|
+
return task instanceof ForeverTask
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* Creates an ForeverTask instance.
|
|
531
|
+
* @param {Retrier} retrier - The retrier instance to use for retry logic
|
|
532
|
+
* @param {Function} task - The task function to execute
|
|
533
|
+
* @param {boolean} resetRetryPolicyAfterSuccess - Whether to reset retry policy after successful execution
|
|
534
|
+
*/
|
|
535
|
+
constructor (retrier, task, resetRetryPolicyAfterSuccess) {
|
|
536
|
+
super(retrier, task);
|
|
537
|
+
this.resetPolicy = resetRetryPolicyAfterSuccess;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/**
|
|
541
|
+
* Executes the task with the given retry parameters.
|
|
542
|
+
* @param {number} retries - The number of retries attempted so far.
|
|
543
|
+
* @param {number} latence - The current latency ms.
|
|
544
|
+
* @param {number} nextInterval - The next interval ms.
|
|
545
|
+
* @returns {Promise<*>} The result of the task execution.
|
|
546
|
+
*/
|
|
547
|
+
async execute (retries, latence, nextInterval) {
|
|
548
|
+
await super.execute(retries, latence, nextInterval);
|
|
549
|
+
if (this.succeeded && this.resetPolicy) {
|
|
550
|
+
this.retrier.resetRetryPolicy();
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
499
555
|
// internal
|
|
500
556
|
|
|
501
557
|
/**
|
|
@@ -504,8 +560,8 @@ class AlwaysTask extends Task {
|
|
|
504
560
|
*/
|
|
505
561
|
|
|
506
562
|
// module vars
|
|
507
|
-
const { assertPositive, assertString, assertFunction, assertNumber } =
|
|
508
|
-
const { isNil } =
|
|
563
|
+
const { assertPositive, assertString, assertFunction, assertNumber } = C;
|
|
564
|
+
const { isNil } = u$1;
|
|
509
565
|
const TaskTimoutFlag = '!#@%$&^*';
|
|
510
566
|
|
|
511
567
|
/**
|
|
@@ -752,7 +808,8 @@ class Retrier {
|
|
|
752
808
|
* @returns {this} The retrier instance for chaining.
|
|
753
809
|
*/
|
|
754
810
|
name (retrierName) {
|
|
755
|
-
assertString(retrierName, '
|
|
811
|
+
assertString(retrierName, 'name');
|
|
812
|
+
this._assertChangeable(retrierName);
|
|
756
813
|
this._name = retrierName;
|
|
757
814
|
return this
|
|
758
815
|
}
|
|
@@ -762,6 +819,7 @@ class Retrier {
|
|
|
762
819
|
* @returns {this} The retrier instance for chaining.
|
|
763
820
|
*/
|
|
764
821
|
infinite () {
|
|
822
|
+
this._assertChangeable('infinite');
|
|
765
823
|
this._maxRetries = Infinity;
|
|
766
824
|
return this
|
|
767
825
|
}
|
|
@@ -772,6 +830,7 @@ class Retrier {
|
|
|
772
830
|
* @returns {this} The Retrier instance for chaining.
|
|
773
831
|
*/
|
|
774
832
|
times (times) {
|
|
833
|
+
this._assertChangeable('times');
|
|
775
834
|
return this.maxRetries(times)
|
|
776
835
|
}
|
|
777
836
|
|
|
@@ -782,6 +841,7 @@ class Retrier {
|
|
|
782
841
|
*/
|
|
783
842
|
maxRetries (maxRetries) {
|
|
784
843
|
assertPositive(maxRetries, 'maxRetries');
|
|
844
|
+
this._assertChangeable('maxRetries');
|
|
785
845
|
this._maxRetries = maxRetries;
|
|
786
846
|
return this
|
|
787
847
|
}
|
|
@@ -793,6 +853,7 @@ class Retrier {
|
|
|
793
853
|
* @throws {Error} If min is not positive or is greater than/equal to max.
|
|
794
854
|
*/
|
|
795
855
|
min (min) {
|
|
856
|
+
this._assertChangeable('min');
|
|
796
857
|
this._policy.min(min);
|
|
797
858
|
return this
|
|
798
859
|
}
|
|
@@ -804,6 +865,7 @@ class Retrier {
|
|
|
804
865
|
* @returns {this} The retrier instance for chaining.
|
|
805
866
|
*/
|
|
806
867
|
max (max) {
|
|
868
|
+
this._assertChangeable('max');
|
|
807
869
|
this._policy.max(max);
|
|
808
870
|
return this
|
|
809
871
|
}
|
|
@@ -816,6 +878,7 @@ class Retrier {
|
|
|
816
878
|
* @throws {Error} If min is not less than max or if values are not positive
|
|
817
879
|
*/
|
|
818
880
|
range (min, max) {
|
|
881
|
+
this._assertChangeable('range');
|
|
819
882
|
this._policy.range(min, max);
|
|
820
883
|
return this
|
|
821
884
|
}
|
|
@@ -826,6 +889,7 @@ class Retrier {
|
|
|
826
889
|
* @returns {Retrier} The Retrier instance for chaining.
|
|
827
890
|
*/
|
|
828
891
|
fixedInterval (fixedInterval) {
|
|
892
|
+
this._assertChangeable('fixedInterval');
|
|
829
893
|
const oldPolicy = this._policy;
|
|
830
894
|
if (oldPolicy instanceof FixedIntervalPolicy) {
|
|
831
895
|
oldPolicy.interval = fixedInterval;
|
|
@@ -845,6 +909,7 @@ class Retrier {
|
|
|
845
909
|
* @returns {Retrier} A retrier instance configured with fixed backoff.
|
|
846
910
|
*/
|
|
847
911
|
fixedBackoff (fixedInterval, jitter = 500) {
|
|
912
|
+
this._assertChangeable('fixedBackoff');
|
|
848
913
|
const oldPolicy = this._policy;
|
|
849
914
|
if (oldPolicy instanceof FixedIntervalPolicy) {
|
|
850
915
|
oldPolicy.interval = fixedInterval;
|
|
@@ -864,6 +929,7 @@ class Retrier {
|
|
|
864
929
|
* @returns {this} The retrier instance for chaining.
|
|
865
930
|
*/
|
|
866
931
|
fixedIncrease (increasement) {
|
|
932
|
+
this._assertChangeable('fixedIncrease');
|
|
867
933
|
const oldPolicy = this._policy;
|
|
868
934
|
if (oldPolicy instanceof FixedIncreasePolicy) {
|
|
869
935
|
oldPolicy.increasement = increasement;
|
|
@@ -883,6 +949,7 @@ class Retrier {
|
|
|
883
949
|
* @returns {this} The retrier instance for chaining.
|
|
884
950
|
*/
|
|
885
951
|
linearBackoff (increasement, jitter = 500) {
|
|
952
|
+
this._assertChangeable('linearBackoff');
|
|
886
953
|
const oldPolicy = this._policy;
|
|
887
954
|
if (oldPolicy instanceof LinearBackoff) {
|
|
888
955
|
oldPolicy.increasement = increasement;
|
|
@@ -902,6 +969,7 @@ class Retrier {
|
|
|
902
969
|
* @returns {this} The retrier instance for method chaining.
|
|
903
970
|
*/
|
|
904
971
|
factorIncrease (factor) {
|
|
972
|
+
this._assertChangeable('factorIncrease');
|
|
905
973
|
const oldPolicy = this._policy;
|
|
906
974
|
if (oldPolicy instanceof FactoreIncreasePolicy) {
|
|
907
975
|
oldPolicy.factor = factor;
|
|
@@ -920,6 +988,7 @@ class Retrier {
|
|
|
920
988
|
* @returns {Retrier} A new Retrier instance
|
|
921
989
|
*/
|
|
922
990
|
exponentialBackoff (jitter = 500) {
|
|
991
|
+
this._assertChangeable('exponentialBackoff');
|
|
923
992
|
const oldPolicy = this._policy;
|
|
924
993
|
if (oldPolicy instanceof ExponentialBackoffPolicy) {
|
|
925
994
|
oldPolicy.jitter = jitter;
|
|
@@ -938,6 +1007,7 @@ class Retrier {
|
|
|
938
1007
|
* @returns {this} The Retrier instance for chaining.
|
|
939
1008
|
*/
|
|
940
1009
|
shuttleInterval (stepLength) {
|
|
1010
|
+
this._assertChangeable('shuttleInterval');
|
|
941
1011
|
const oldPolicy = this._policy;
|
|
942
1012
|
if (oldPolicy instanceof ShuttlePolicy) {
|
|
943
1013
|
oldPolicy.stepLength = stepLength;
|
|
@@ -957,7 +1027,8 @@ class Retrier {
|
|
|
957
1027
|
* @returns {this} The retrier instance for chaining.
|
|
958
1028
|
*/
|
|
959
1029
|
taskTimeout (timeout) {
|
|
960
|
-
assertPositive(timeout, '
|
|
1030
|
+
assertPositive(timeout, 'taskTimeout');
|
|
1031
|
+
this._assertChangeable('taskTimeout');
|
|
961
1032
|
this._taskTimeout = timeout;
|
|
962
1033
|
return this
|
|
963
1034
|
}
|
|
@@ -971,6 +1042,7 @@ class Retrier {
|
|
|
971
1042
|
*/
|
|
972
1043
|
timeout (timeout) {
|
|
973
1044
|
assertNumber(timeout, 'timeout');
|
|
1045
|
+
this._assertChangeable('timeout');
|
|
974
1046
|
this._timeout = timeout;
|
|
975
1047
|
return this
|
|
976
1048
|
}
|
|
@@ -979,7 +1051,8 @@ class Retrier {
|
|
|
979
1051
|
* Disables the timeout for the retrier.
|
|
980
1052
|
* @returns {this} The retrier instance for chaining.
|
|
981
1053
|
*/
|
|
982
|
-
|
|
1054
|
+
noTimeout () {
|
|
1055
|
+
this._assertChangeable('noTimeout');
|
|
983
1056
|
this._timeout = 0;
|
|
984
1057
|
return this
|
|
985
1058
|
}
|
|
@@ -991,6 +1064,7 @@ class Retrier {
|
|
|
991
1064
|
*/
|
|
992
1065
|
task (task) {
|
|
993
1066
|
assertFunction(task, 'task');
|
|
1067
|
+
this._assertChangeable('task');
|
|
994
1068
|
this._task = new Task(this, task);
|
|
995
1069
|
return this
|
|
996
1070
|
}
|
|
@@ -1001,6 +1075,7 @@ class Retrier {
|
|
|
1001
1075
|
* @return {this}
|
|
1002
1076
|
*/
|
|
1003
1077
|
retry (task) {
|
|
1078
|
+
this._assertChangeable('retry');
|
|
1004
1079
|
this.task(task);
|
|
1005
1080
|
return this
|
|
1006
1081
|
}
|
|
@@ -1010,14 +1085,31 @@ class Retrier {
|
|
|
1010
1085
|
* 1. if the task fails, will retry it after the interval generated by RetryPolicy
|
|
1011
1086
|
* 2. if the task succeeds, reset RetryPolicy to Minimum Interval and continue to run the task
|
|
1012
1087
|
* @param {Function} task - The async function to execute and retry.
|
|
1013
|
-
* @param {boolean} [resetAfterSuccess=
|
|
1088
|
+
* @param {boolean} [resetAfterSuccess=true] - Whether to reset retry counters after success.
|
|
1014
1089
|
* @returns {this} The Retrier instance for chaining.
|
|
1015
1090
|
*/
|
|
1016
|
-
always (task, resetAfterSuccess =
|
|
1091
|
+
always (task, resetAfterSuccess = true) {
|
|
1092
|
+
this._assertChangeable('always');
|
|
1017
1093
|
this._task = new AlwaysTask(this, task, resetAfterSuccess);
|
|
1018
1094
|
return this
|
|
1019
1095
|
}
|
|
1020
1096
|
|
|
1097
|
+
/**
|
|
1098
|
+
*The task will execute forever despite of failure or success.
|
|
1099
|
+
* 1. call notimeout(), override and ignore Retrier total timeout setting
|
|
1100
|
+
* 2. call infinite(), override and ignore Retrier max retries setting
|
|
1101
|
+
* @param {Function} task
|
|
1102
|
+
* @param {boolean} [resetAfterSuccess=true]
|
|
1103
|
+
* @returns
|
|
1104
|
+
*/
|
|
1105
|
+
forever (task, resetAfterSuccess = true) {
|
|
1106
|
+
this._assertChangeable('forever');
|
|
1107
|
+
this.noTimeout();
|
|
1108
|
+
this.infinite();
|
|
1109
|
+
this._task = new ForeverTask(this, task, resetAfterSuccess);
|
|
1110
|
+
return this
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1021
1113
|
/**
|
|
1022
1114
|
* Starts the retry process.
|
|
1023
1115
|
* @returns {Promise<*>}
|
|
@@ -1029,108 +1121,16 @@ class Retrier {
|
|
|
1029
1121
|
if (this._taskingFlag != null) {
|
|
1030
1122
|
return this._taskingFlag.promise
|
|
1031
1123
|
}
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
* DO NOT worry about "while(true)", we will not be trapped in an infinite loop.
|
|
1042
|
-
*
|
|
1043
|
-
* "async" keyword ensures:
|
|
1044
|
-
* 1. call start(), will enfore the first loop executed
|
|
1045
|
-
* 2. when first "await" is encountered, "while(true)" loop hanged to wait
|
|
1046
|
-
* 3. "async" will return a Promise when "while(true)" loop hanged
|
|
1047
|
-
* 4. Returned "async" wrapper Promise, it is NOT "this._taskingFlag.promise"
|
|
1048
|
-
*/
|
|
1049
|
-
while (true) {
|
|
1050
|
-
// need to stop?
|
|
1051
|
-
if (this._breakFlag != null) {
|
|
1052
|
-
this._taskingFlag.reject(this._breakReason ?? new Error('Have Been Broken'));
|
|
1053
|
-
break
|
|
1054
|
-
}
|
|
1055
|
-
|
|
1056
|
-
latency = Date.now() - startAt;
|
|
1057
|
-
|
|
1058
|
-
// total timeout?
|
|
1059
|
-
if (!isInfinite(this._timeout) && latency >= this._timeout) { // total timeout
|
|
1060
|
-
// @ts-ignore
|
|
1061
|
-
this.emit(Event.Timeout, this._currentRetries, latency, this._timeout);
|
|
1062
|
-
// always task, treat as success, resolve the whole promise with <void>
|
|
1063
|
-
if (AlwaysTask.isAlwaysTask(this._task)) {
|
|
1064
|
-
this._taskingFlag.resolve();
|
|
1065
|
-
break
|
|
1066
|
-
}
|
|
1067
|
-
this._taskingFlag.reject(lastError ?? new Error(`Timeout "${this._timeout}" Exceeded`));
|
|
1068
|
-
break
|
|
1069
|
-
}
|
|
1070
|
-
|
|
1071
|
-
// @ts-ignore
|
|
1072
|
-
this.emit(Event.Retry, this._currentRetries, latency);
|
|
1073
|
-
const task = this._task; // take task, it may be changed in events' callback functions
|
|
1074
|
-
const nextDelay = this._policy.generate(this._currentRetries);
|
|
1075
|
-
try {
|
|
1076
|
-
try {
|
|
1077
|
-
await tt.timeout(task.execute(this._currentRetries, latency, nextDelay), this._taskTimeout, TaskTimoutFlag);
|
|
1078
|
-
} catch (err) {
|
|
1079
|
-
// @ts-ignore
|
|
1080
|
-
if (err.message === TaskTimoutFlag) {
|
|
1081
|
-
// @ts-ignore
|
|
1082
|
-
this.emit(Event.TaskTimeout, this._currentRetries, latency, this._taskTimeout);
|
|
1083
|
-
}
|
|
1084
|
-
throw err
|
|
1085
|
-
}
|
|
1086
|
-
// @ts-ignore
|
|
1087
|
-
if (task.failed) {
|
|
1088
|
-
lastError = task.error;
|
|
1089
|
-
throw task.error
|
|
1090
|
-
}
|
|
1091
|
-
const rtnVal = task.result;
|
|
1092
|
-
// @ts-ignore
|
|
1093
|
-
this.emit(Event.Success, rtnVal, this._currentRetries, latency);
|
|
1094
|
-
|
|
1095
|
-
// Not AwaysTask, we can finish all the retries with success
|
|
1096
|
-
if (!AlwaysTask.isAlwaysTask(task)) {
|
|
1097
|
-
this._taskingFlag.resolve(rtnVal);
|
|
1098
|
-
break
|
|
1099
|
-
}
|
|
1100
|
-
// AwaysTask, continue to run the task
|
|
1101
|
-
} catch (e) {
|
|
1102
|
-
// @ts-ignore
|
|
1103
|
-
this.emit(Event.Failure, e, this._currentRetries, latency);
|
|
1104
|
-
}
|
|
1105
|
-
const nextRetries = ++this._currentRetries;
|
|
1106
|
-
// next retry, max retries reached?
|
|
1107
|
-
if (this._currentRetries > this._maxRetries) {
|
|
1108
|
-
// @ts-ignore
|
|
1109
|
-
this.emit(Event.MaxRetries, nextRetries, this._maxRetries);
|
|
1110
|
-
// always task, treat as success, resolve the whole promise with <void>
|
|
1111
|
-
if (AlwaysTask.isAlwaysTask(task)) {
|
|
1112
|
-
this._taskingFlag.resolve();
|
|
1113
|
-
break
|
|
1114
|
-
}
|
|
1115
|
-
this._taskingFlag.reject(lastError ?? new Error(`Max Retries Exceeded, Retring ${this._currentRetries} times > max ${this._maxRetries}`));
|
|
1116
|
-
break
|
|
1117
|
-
}
|
|
1118
|
-
// use Waiter to introduce the ability to wakeup at any time
|
|
1119
|
-
this._sleepWaiter = tt.wait(nextDelay);
|
|
1120
|
-
await this._sleepWaiter.promise;
|
|
1121
|
-
// await PromiseUtils.delay(nextDelay)
|
|
1122
|
-
}
|
|
1123
|
-
this._taskingFlag.promise.finally(() => {
|
|
1124
|
-
this.resetRetryPolicy();
|
|
1125
|
-
this._taskingFlag = undefined;
|
|
1126
|
-
const spent = Date.now() - startAt;
|
|
1127
|
-
// @ts-ignore
|
|
1128
|
-
this.emit(Event.Completed, this._currentRetries, spent);
|
|
1129
|
-
});
|
|
1130
|
-
if (AlwaysTask.isAlwaysTask(this._task)) {
|
|
1131
|
-
return // always task, resolve with <void>
|
|
1124
|
+
this._taskingFlag = rt.defer();
|
|
1125
|
+
|
|
1126
|
+
if (ForeverTask.isForeverTask(this._task)) {
|
|
1127
|
+
// DO NOT care ForeverTask's result
|
|
1128
|
+
this._executeForeverTask(this._task);
|
|
1129
|
+
this._taskingFlag.resolve();
|
|
1130
|
+
} else {
|
|
1131
|
+
// Resovle taskingFlag.promise in method _executeEndableTask()
|
|
1132
|
+
this._executeEndableTask(this._task);
|
|
1132
1133
|
}
|
|
1133
|
-
// normal retry task, return the task's result
|
|
1134
1134
|
return this._taskingFlag.promise
|
|
1135
1135
|
}
|
|
1136
1136
|
|
|
@@ -1162,7 +1162,11 @@ class Retrier {
|
|
|
1162
1162
|
// @ts-ignore
|
|
1163
1163
|
return this._breakFlag.promise
|
|
1164
1164
|
}
|
|
1165
|
-
|
|
1165
|
+
// kick off
|
|
1166
|
+
if (this._sleepWaiter != null) {
|
|
1167
|
+
this._sleepWaiter.wakeup();
|
|
1168
|
+
}
|
|
1169
|
+
this._breakFlag = rt.defer();
|
|
1166
1170
|
/** @type {Error|undefined} */
|
|
1167
1171
|
this._breakReason = reason ?? new Error('Manually Stop');
|
|
1168
1172
|
// @ts-ignore
|
|
@@ -1291,6 +1295,184 @@ class Retrier {
|
|
|
1291
1295
|
this.on(Event.MaxRetries, listener);
|
|
1292
1296
|
return this
|
|
1293
1297
|
}
|
|
1298
|
+
|
|
1299
|
+
/**
|
|
1300
|
+
*
|
|
1301
|
+
* @param {Task} task
|
|
1302
|
+
* @returns {Promise<void>}
|
|
1303
|
+
*/
|
|
1304
|
+
async _executeForeverTask (task) {
|
|
1305
|
+
if (this._taskingFlag == null) {
|
|
1306
|
+
throw new Error('Must be called in start()')
|
|
1307
|
+
}
|
|
1308
|
+
const startAt = Date.now();
|
|
1309
|
+
// @ts-ignore
|
|
1310
|
+
this.emit(Event.Start, startAt);
|
|
1311
|
+
let latency = null;
|
|
1312
|
+
|
|
1313
|
+
while (true) {
|
|
1314
|
+
// need to stop?
|
|
1315
|
+
if (this._breakFlag != null) {
|
|
1316
|
+
const spent = Date.now() - startAt;
|
|
1317
|
+
// @ts-ignore
|
|
1318
|
+
this.emit(Event.Completed, this._currentRetries, spent);
|
|
1319
|
+
break
|
|
1320
|
+
}
|
|
1321
|
+
latency = Date.now() - startAt;
|
|
1322
|
+
// @ts-ignore
|
|
1323
|
+
this.emit(Event.Retry, this._currentRetries, latency);
|
|
1324
|
+
const nextDelay = this._policy.generate(this._currentRetries);
|
|
1325
|
+
try {
|
|
1326
|
+
try {
|
|
1327
|
+
await rt.timeout(task.execute(this._currentRetries, latency, nextDelay), this._taskTimeout, TaskTimoutFlag);
|
|
1328
|
+
} catch (err) {
|
|
1329
|
+
// @ts-ignore
|
|
1330
|
+
if (err.message === TaskTimoutFlag) {
|
|
1331
|
+
// @ts-ignore
|
|
1332
|
+
this.emit(Event.TaskTimeout, this._currentRetries, latency, this._taskTimeout);
|
|
1333
|
+
}
|
|
1334
|
+
throw err
|
|
1335
|
+
}
|
|
1336
|
+
// @ts-ignore
|
|
1337
|
+
if (task.failed) {
|
|
1338
|
+
throw task.error
|
|
1339
|
+
}
|
|
1340
|
+
const rtnVal = task.result;
|
|
1341
|
+
// @ts-ignore
|
|
1342
|
+
this.emit(Event.Success, rtnVal, this._currentRetries, latency);
|
|
1343
|
+
// continue to run the task
|
|
1344
|
+
} catch (e) {
|
|
1345
|
+
// @ts-ignore
|
|
1346
|
+
this.emit(Event.Failure, e, this._currentRetries, latency);
|
|
1347
|
+
}
|
|
1348
|
+
// compute next retry counter
|
|
1349
|
+
++this._currentRetries;
|
|
1350
|
+
// use Waiter to introduce the ability to wakeup at any time
|
|
1351
|
+
this._sleepWaiter = rt.wait(nextDelay);
|
|
1352
|
+
await this._sleepWaiter.promise;
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
/**
|
|
1357
|
+
* @param {Task} task
|
|
1358
|
+
* @returns {Promise<any>}
|
|
1359
|
+
*/
|
|
1360
|
+
async _executeEndableTask (task) {
|
|
1361
|
+
if (this._taskingFlag == null) {
|
|
1362
|
+
throw new Error('Must be called in start()')
|
|
1363
|
+
}
|
|
1364
|
+
const startAt = Date.now();
|
|
1365
|
+
/** @type {Error|undefined} */
|
|
1366
|
+
let lastError;
|
|
1367
|
+
// @ts-ignore
|
|
1368
|
+
this.emit(Event.Start, startAt);
|
|
1369
|
+
let latency = null;
|
|
1370
|
+
|
|
1371
|
+
/**
|
|
1372
|
+
* DO NOT worry about "while(true)", we will not be trapped in an infinite loop.
|
|
1373
|
+
*
|
|
1374
|
+
* "async" keyword ensures:
|
|
1375
|
+
* 1. call start(), will enfore the first loop executed
|
|
1376
|
+
* 2. when first "await" is encountered, "while(true)" loop hanged to wait
|
|
1377
|
+
* 3. "async" will return a Promise when "while(true)" loop hanged
|
|
1378
|
+
* 4. Returned "async" wrapper Promise, it is NOT "this._taskingFlag.promise"
|
|
1379
|
+
*/
|
|
1380
|
+
while (true) {
|
|
1381
|
+
// need to stop?
|
|
1382
|
+
if (this._breakFlag != null) {
|
|
1383
|
+
this._taskingFlag.reject(this._breakReason ?? new Error('Have Been Broken'));
|
|
1384
|
+
break
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
latency = Date.now() - startAt;
|
|
1388
|
+
|
|
1389
|
+
// total timeout?
|
|
1390
|
+
if (!isInfinite(this._timeout) && latency >= this._timeout) { // total timeout
|
|
1391
|
+
// @ts-ignore
|
|
1392
|
+
this.emit(Event.Timeout, this._currentRetries, latency, this._timeout);
|
|
1393
|
+
// always task, treat as success, resolve the whole promise with <void>
|
|
1394
|
+
if (AlwaysTask.isAlwaysTask(this._task)) {
|
|
1395
|
+
this._taskingFlag.resolve();
|
|
1396
|
+
break
|
|
1397
|
+
}
|
|
1398
|
+
this._taskingFlag.reject(lastError ?? new Error(`Timeout "${this._timeout}" Exceeded`));
|
|
1399
|
+
break
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
// @ts-ignore
|
|
1403
|
+
this.emit(Event.Retry, this._currentRetries, latency);
|
|
1404
|
+
const nextDelay = this._policy.generate(this._currentRetries);
|
|
1405
|
+
try {
|
|
1406
|
+
try {
|
|
1407
|
+
await rt.timeout(task.execute(this._currentRetries, latency, nextDelay), this._taskTimeout, TaskTimoutFlag);
|
|
1408
|
+
} catch (err) {
|
|
1409
|
+
// @ts-ignore
|
|
1410
|
+
if (err.message === TaskTimoutFlag) {
|
|
1411
|
+
// @ts-ignore
|
|
1412
|
+
this.emit(Event.TaskTimeout, this._currentRetries, latency, this._taskTimeout);
|
|
1413
|
+
}
|
|
1414
|
+
throw err
|
|
1415
|
+
}
|
|
1416
|
+
// @ts-ignore
|
|
1417
|
+
if (task.failed) {
|
|
1418
|
+
lastError = task.error;
|
|
1419
|
+
throw task.error
|
|
1420
|
+
}
|
|
1421
|
+
const rtnVal = task.result;
|
|
1422
|
+
// @ts-ignore
|
|
1423
|
+
this.emit(Event.Success, rtnVal, this._currentRetries, latency);
|
|
1424
|
+
|
|
1425
|
+
// Not AwaysTask, we can finish all the retries with success
|
|
1426
|
+
if (!AlwaysTask.isAlwaysTask(task)) {
|
|
1427
|
+
this._taskingFlag.resolve(rtnVal);
|
|
1428
|
+
break
|
|
1429
|
+
}
|
|
1430
|
+
// AwaysTask, continue to run the task
|
|
1431
|
+
} catch (e) {
|
|
1432
|
+
// @ts-ignore
|
|
1433
|
+
this.emit(Event.Failure, e, this._currentRetries, latency);
|
|
1434
|
+
}
|
|
1435
|
+
const nextRetries = ++this._currentRetries;
|
|
1436
|
+
// next retry, max retries reached?
|
|
1437
|
+
if (this._currentRetries > this._maxRetries) {
|
|
1438
|
+
// @ts-ignore
|
|
1439
|
+
this.emit(Event.MaxRetries, nextRetries, this._maxRetries);
|
|
1440
|
+
// always task, treat as success, resolve the whole promise with <void>
|
|
1441
|
+
if (AlwaysTask.isAlwaysTask(task)) {
|
|
1442
|
+
this._taskingFlag.resolve();
|
|
1443
|
+
break
|
|
1444
|
+
}
|
|
1445
|
+
this._taskingFlag.reject(lastError ?? new Error(`Max Retries Exceeded, Retring ${this._currentRetries} times > max ${this._maxRetries}`));
|
|
1446
|
+
break
|
|
1447
|
+
}
|
|
1448
|
+
// use Waiter to introduce the ability to wakeup at any time
|
|
1449
|
+
this._sleepWaiter = rt.wait(nextDelay);
|
|
1450
|
+
await this._sleepWaiter.promise;
|
|
1451
|
+
// await PromiseUtils.delay(nextDelay)
|
|
1452
|
+
}
|
|
1453
|
+
this._taskingFlag.promise.finally(() => {
|
|
1454
|
+
this.resetRetryPolicy();
|
|
1455
|
+
this._taskingFlag = undefined;
|
|
1456
|
+
const spent = Date.now() - startAt;
|
|
1457
|
+
// @ts-ignore
|
|
1458
|
+
this.emit(Event.Completed, this._currentRetries, spent);
|
|
1459
|
+
});
|
|
1460
|
+
if (AlwaysTask.isAlwaysTask(this._task)) {
|
|
1461
|
+
return // always task, resolve with <void>
|
|
1462
|
+
}
|
|
1463
|
+
// normal retry task, return the task's result
|
|
1464
|
+
return this._taskingFlag.promise
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
/**
|
|
1468
|
+
* Assert if can change param's value
|
|
1469
|
+
* @param {string} param
|
|
1470
|
+
*/
|
|
1471
|
+
_assertChangeable (param) {
|
|
1472
|
+
if (this._taskingFlag != null) {
|
|
1473
|
+
throw new Error(`No Change "${param}" After Retrier Started`)
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1294
1476
|
}
|
|
1295
1477
|
|
|
1296
1478
|
/**
|
|
@@ -1524,7 +1706,7 @@ var RetrierFactory = {
|
|
|
1524
1706
|
* ...
|
|
1525
1707
|
* ```
|
|
1526
1708
|
*/
|
|
1527
|
-
|
|
1709
|
+
n$1.defaults(Retrier, RetrierFactory);
|
|
1528
1710
|
|
|
1529
1711
|
/**
|
|
1530
1712
|
* default export to support
|