@creejs/commons-retrier 1.0.8 → 2.0.2
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 +1151 -0
- package/dist/cjs/index-dev.cjs.map +1 -0
- package/dist/cjs/index-min.cjs +2 -0
- package/dist/cjs/index-min.cjs.map +1 -0
- package/dist/esm/index-dev.js +1129 -0
- package/dist/esm/index-dev.js.map +1 -0
- package/dist/esm/index-min.js +2 -0
- package/dist/esm/index-min.js.map +1 -0
- package/dist/umd/index.dev.js +1157 -0
- package/dist/umd/index.dev.js.map +1 -0
- package/dist/umd/index.min.js +2 -0
- package/dist/umd/index.min.js.map +1 -0
- package/package.json +8 -10
- package/lib/alway-task.js +0 -44
- package/lib/constants.js +0 -9
- package/lib/event.js +0 -21
- package/lib/index.js +0 -44
- package/lib/policy/factor-increase-policy.js +0 -46
- package/lib/policy/fixed-increase-policy.js +0 -39
- package/lib/policy/fixed-interval-policy.js +0 -38
- package/lib/policy/shuttle-policy.js +0 -50
- package/lib/policy.js +0 -130
- package/lib/retrier-factory.js +0 -191
- package/lib/retrier.js +0 -530
- package/lib/task.js +0 -58
package/lib/retrier.js
DELETED
|
@@ -1,530 +0,0 @@
|
|
|
1
|
-
// internal
|
|
2
|
-
import { TypeAssert, TypeUtils, PromiseUtils } from '@creejs/commons-lang'
|
|
3
|
-
import { EventEmitter } from '@creejs/commons-events'
|
|
4
|
-
|
|
5
|
-
// owned
|
|
6
|
-
// eslint-disable-next-line no-unused-vars
|
|
7
|
-
import Policy from './policy.js'
|
|
8
|
-
import Event from './event.js'
|
|
9
|
-
import FixedIntervalPolicy from './policy/fixed-interval-policy.js'
|
|
10
|
-
import FixedIncreasePolicy from './policy/fixed-increase-policy.js'
|
|
11
|
-
import FactoreIncreasePolicy from './policy/factor-increase-policy.js'
|
|
12
|
-
import ShuttlePolicy from './policy/shuttle-policy.js'
|
|
13
|
-
import Task from './task.js'
|
|
14
|
-
import AlwaysTask from './alway-task.js'
|
|
15
|
-
import { DefaultMaxRetries } from './constants.js'
|
|
16
|
-
|
|
17
|
-
// module vars
|
|
18
|
-
const { assertPositive, assertString, assertFunction, assertNumber } = TypeAssert
|
|
19
|
-
const { isNil } = TypeUtils
|
|
20
|
-
const TaskTimoutFlag = '!#@%$&^*'
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* @extends EventEmitter
|
|
24
|
-
*/
|
|
25
|
-
export default class Retrier {
|
|
26
|
-
/**
|
|
27
|
-
* Creates a new Retrier instance with a fixed interval policy.
|
|
28
|
-
* @param {number} [fixedInterval=1000] - The fixed interval in milliseconds between retry attempts. Defaults to 1000ms if not provided.
|
|
29
|
-
*/
|
|
30
|
-
constructor (fixedInterval) {
|
|
31
|
-
EventEmitter.mixin(this)
|
|
32
|
-
/**
|
|
33
|
-
* @type {Policy}
|
|
34
|
-
*/
|
|
35
|
-
this._policy = new FixedIntervalPolicy(fixedInterval ?? 1000)
|
|
36
|
-
this._maxRetries = DefaultMaxRetries
|
|
37
|
-
this._currentRetries = 1
|
|
38
|
-
/**
|
|
39
|
-
* Timetou for total operation
|
|
40
|
-
* @type {number}
|
|
41
|
-
*/
|
|
42
|
-
this._timeout = 120000 // 120s
|
|
43
|
-
/**
|
|
44
|
-
* Timetou for single task
|
|
45
|
-
*/
|
|
46
|
-
this._taskTimeout = 2000 // 20s
|
|
47
|
-
this._name = 'unamed' // Retrier name
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* A Deferred Object as Singal to prevent Task concurrent start
|
|
51
|
-
* @type {{resolve:Function, reject:Function, promise: Promise<*>}|undefined}
|
|
52
|
-
*/
|
|
53
|
-
this._taskingFlag = undefined
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* A Deferred Object as Singal to prevent Task concurrent stop
|
|
57
|
-
* @type {{resolve:Function, reject:Function, promise: Promise<*>}|undefined}
|
|
58
|
-
*/
|
|
59
|
-
this._breakFlag = undefined
|
|
60
|
-
/**
|
|
61
|
-
* Reason for break
|
|
62
|
-
* @type {Error|undefined}
|
|
63
|
-
*/
|
|
64
|
-
this._breakReason = undefined
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
get running () {
|
|
68
|
-
return !isNil(this._taskingFlag)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Sets the name of the retrier.
|
|
73
|
-
* @param {string} retrierName - The name to assign to the retrier.
|
|
74
|
-
* @returns {this} The retrier instance for chaining.
|
|
75
|
-
*/
|
|
76
|
-
name (retrierName) {
|
|
77
|
-
assertString(retrierName, 'retrierName')
|
|
78
|
-
this._name = retrierName
|
|
79
|
-
return this
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Sets the retry attempts to be infinite by setting max retries to maximum safe integer.
|
|
84
|
-
* @returns {Object} The retrier instance for chaining.
|
|
85
|
-
*/
|
|
86
|
-
infinite () {
|
|
87
|
-
this._maxRetries = Infinity
|
|
88
|
-
return this
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Sets the maximum number of retry attempts.
|
|
93
|
-
* @param {number} times - The maximum number of retries.
|
|
94
|
-
* @returns {this} The Retrier instance for chaining.
|
|
95
|
-
*/
|
|
96
|
-
times (times) {
|
|
97
|
-
return this.maxRetries(times)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Sets the maximum number of retry attempts.
|
|
102
|
-
* @param {number} maxRetries - The maximum number of retries (must be positive).
|
|
103
|
-
* @returns {this} The retrier instance for chaining.
|
|
104
|
-
*/
|
|
105
|
-
maxRetries (maxRetries) {
|
|
106
|
-
assertPositive(maxRetries, 'maxRetries')
|
|
107
|
-
this._maxRetries = maxRetries
|
|
108
|
-
return this
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Sets the minimum retry delay in milliseconds.
|
|
113
|
-
* @param {number} min - The minimum delay (must be positive and less than max).
|
|
114
|
-
* @returns {this} The retrier instance for chaining.
|
|
115
|
-
* @throws {Error} If min is not positive or is greater than/equal to max.
|
|
116
|
-
*/
|
|
117
|
-
min (min) {
|
|
118
|
-
this._policy.min(min)
|
|
119
|
-
return this
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Sets the maximum retry retry delay in milliseconds.
|
|
124
|
-
* @param {number} max - The maximum delay (must be positive and greater than min).
|
|
125
|
-
* @throws {Error} If max is not greater than min.
|
|
126
|
-
* @returns {this} The retrier instance for chaining.
|
|
127
|
-
*/
|
|
128
|
-
max (max) {
|
|
129
|
-
this._policy.max(max)
|
|
130
|
-
return this
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Sets the minimum and maximum intervals for retries.
|
|
135
|
-
* @param {number} min - Minimum delay in milliseconds (must be positive and less than max)
|
|
136
|
-
* @param {number} max - Maximum delay in milliseconds (must be positive and greater than min)
|
|
137
|
-
* @returns {Retrier} Returns the Retrier instance for chaining
|
|
138
|
-
* @throws {Error} If min is not less than max or if values are not positive
|
|
139
|
-
*/
|
|
140
|
-
range (min, max) {
|
|
141
|
-
this._policy.range(min, max)
|
|
142
|
-
return this
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Sets a fixed interval retry policy.
|
|
147
|
-
* @param {number} fixedInterval - The fixed interval in milliseconds between retries.
|
|
148
|
-
* @returns {Retrier} The Retrier instance for chaining.
|
|
149
|
-
*/
|
|
150
|
-
fixedInterval (fixedInterval) {
|
|
151
|
-
const oldPolicy = this._policy
|
|
152
|
-
if (oldPolicy instanceof FixedIntervalPolicy) {
|
|
153
|
-
oldPolicy.interval = fixedInterval
|
|
154
|
-
return this
|
|
155
|
-
}
|
|
156
|
-
const newPolicy = new FixedIntervalPolicy(fixedInterval)
|
|
157
|
-
oldPolicy?.copyPolicySetting(newPolicy)
|
|
158
|
-
newPolicy.reset()
|
|
159
|
-
this._policy = newPolicy
|
|
160
|
-
return this
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Sets a fixed increase policy for retry intervals.
|
|
165
|
-
* @param {number} increasement - The fixed amount to increase the interval by on each retry.
|
|
166
|
-
* @returns {this} The retrier instance for chaining.
|
|
167
|
-
*/
|
|
168
|
-
fixedIncrease (increasement) {
|
|
169
|
-
const oldPolicy = this._policy
|
|
170
|
-
if (oldPolicy instanceof FixedIncreasePolicy) {
|
|
171
|
-
oldPolicy.increasement = increasement
|
|
172
|
-
return this
|
|
173
|
-
}
|
|
174
|
-
const newPolicy = new FixedIncreasePolicy(increasement)
|
|
175
|
-
oldPolicy?.copyPolicySetting(newPolicy)
|
|
176
|
-
newPolicy.reset()
|
|
177
|
-
this._policy = newPolicy
|
|
178
|
-
return this
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Sets a fixed increase factor for retry delays.
|
|
183
|
-
* @param {number} factor - The multiplier for delay increase between retries.
|
|
184
|
-
* @returns {this} The retrier instance for method chaining.
|
|
185
|
-
*/
|
|
186
|
-
factorIncrease (factor) {
|
|
187
|
-
const oldPolicy = this._policy
|
|
188
|
-
if (oldPolicy instanceof FactoreIncreasePolicy) {
|
|
189
|
-
oldPolicy.factor = factor
|
|
190
|
-
return this
|
|
191
|
-
}
|
|
192
|
-
const newPolicy = new FactoreIncreasePolicy(factor)
|
|
193
|
-
oldPolicy?.copyPolicySetting(newPolicy)
|
|
194
|
-
newPolicy.reset()
|
|
195
|
-
this._policy = newPolicy
|
|
196
|
-
return this
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Sets a shuttle retry policy with the given step length.
|
|
201
|
-
* @param {number} stepLength - The interval between retry attempts.
|
|
202
|
-
* @returns {this} The Retrier instance for chaining.
|
|
203
|
-
*/
|
|
204
|
-
shuttleInterval (stepLength) {
|
|
205
|
-
const oldPolicy = this._policy
|
|
206
|
-
if (oldPolicy instanceof ShuttlePolicy) {
|
|
207
|
-
oldPolicy.stepLength = stepLength
|
|
208
|
-
return this
|
|
209
|
-
}
|
|
210
|
-
const newPolicy = new ShuttlePolicy(stepLength)
|
|
211
|
-
oldPolicy?.copyPolicySetting(newPolicy)
|
|
212
|
-
newPolicy.reset()
|
|
213
|
-
this._policy = newPolicy
|
|
214
|
-
return this
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Sets the timeout duration for each Task execution.
|
|
219
|
-
* 1. must > 0
|
|
220
|
-
* @param {number} timeout - The timeout duration in milliseconds.
|
|
221
|
-
* @returns {Object} The retrier instance for chaining.
|
|
222
|
-
*/
|
|
223
|
-
taskTimeout (timeout) {
|
|
224
|
-
assertPositive(timeout, 'timeout')
|
|
225
|
-
this._taskTimeout = timeout
|
|
226
|
-
return this
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Sets the timeout duration for all retries.
|
|
231
|
-
* 1. <= 0 - no timeout
|
|
232
|
-
* 2. \> 0 - timeout duration in milliseconds
|
|
233
|
-
* @param {number} timeout - The timeout duration in milliseconds.
|
|
234
|
-
* @returns {Object} The retrier instance for chaining.
|
|
235
|
-
*/
|
|
236
|
-
timeout (timeout) {
|
|
237
|
-
assertNumber(timeout, 'timeout')
|
|
238
|
-
this._timeout = timeout
|
|
239
|
-
return this
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Sets the task function to be retried.
|
|
244
|
-
* @param {Function} task - The function to be executed and retried on failure.
|
|
245
|
-
* @returns {this} Returns the retrier instance for chaining.
|
|
246
|
-
*/
|
|
247
|
-
task (task) {
|
|
248
|
-
assertFunction(task, 'task')
|
|
249
|
-
this._task = new Task(this, task)
|
|
250
|
-
return this
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* alias of {@linkcode Retrier.task()}
|
|
255
|
-
* @param {Function} task - The function to be executed and retried
|
|
256
|
-
* @return {this}
|
|
257
|
-
*/
|
|
258
|
-
retry (task) {
|
|
259
|
-
this.task(task)
|
|
260
|
-
return this
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Executes the given task, and never stop
|
|
265
|
-
* 1. if the task fails, will retry it after the interval generated by RetryPolicy
|
|
266
|
-
* 2. if the task succeeds, reset RetryPolicy to Minimum Interval and continue to run the task
|
|
267
|
-
* @param {Function} task - The async function to execute and retry.
|
|
268
|
-
* @param {boolean} [resetAfterSuccess=false] - Whether to reset retry counters after success.
|
|
269
|
-
* @returns {this} The Retrier instance for chaining.
|
|
270
|
-
*/
|
|
271
|
-
always (task, resetAfterSuccess = false) {
|
|
272
|
-
this._task = new AlwaysTask(this, task, resetAfterSuccess)
|
|
273
|
-
return this
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* Starts the retry process.
|
|
278
|
-
* @returns {Promise<*>}
|
|
279
|
-
*/
|
|
280
|
-
async start () {
|
|
281
|
-
if (this._task == null) {
|
|
282
|
-
throw new Error('No Task to Retry')
|
|
283
|
-
}
|
|
284
|
-
if (this._taskingFlag != null) {
|
|
285
|
-
return this._taskingFlag.promise
|
|
286
|
-
}
|
|
287
|
-
const startAt = Date.now()
|
|
288
|
-
let lastError = null
|
|
289
|
-
// @ts-ignore
|
|
290
|
-
this.emit(Event.Start, startAt)
|
|
291
|
-
this._taskingFlag = PromiseUtils.defer()
|
|
292
|
-
let latency = null
|
|
293
|
-
while (true) {
|
|
294
|
-
// need to stop?
|
|
295
|
-
if (this._breakFlag != null) {
|
|
296
|
-
this._taskingFlag.reject(this._breakReason)
|
|
297
|
-
break
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
latency = Date.now() - startAt
|
|
301
|
-
|
|
302
|
-
// total timeout?
|
|
303
|
-
if (!isInfinite(this._timeout) && latency >= this._timeout) { // total timeout
|
|
304
|
-
// @ts-ignore
|
|
305
|
-
this.emit(Event.Timeout, this._currentRetries, latency, this._timeout)
|
|
306
|
-
// always task, treat as success, resolve the whole promise with <void>
|
|
307
|
-
if (AlwaysTask.isAlwaysTask(this._task)) {
|
|
308
|
-
this._taskingFlag.resolve()
|
|
309
|
-
break
|
|
310
|
-
}
|
|
311
|
-
this._taskingFlag.reject(lastError ?? new Error(`Timeout "${this._timeout}" Exceeded`))
|
|
312
|
-
break
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
// @ts-ignore
|
|
316
|
-
this.emit(Event.Retry, this._currentRetries, latency)
|
|
317
|
-
const task = this._task // take task, it may be changed in events' callback functions
|
|
318
|
-
const nextDelay = this._policy.generate()
|
|
319
|
-
try {
|
|
320
|
-
try {
|
|
321
|
-
await PromiseUtils.timeout(task.execute(this._currentRetries, latency, nextDelay), this._taskTimeout, TaskTimoutFlag)
|
|
322
|
-
} catch (err) {
|
|
323
|
-
// @ts-ignore
|
|
324
|
-
if (err.message === TaskTimoutFlag) {
|
|
325
|
-
// @ts-ignore
|
|
326
|
-
this.emit(Event.TaskTimeout, this._currentRetries, latency, this._taskTimeout)
|
|
327
|
-
}
|
|
328
|
-
throw err
|
|
329
|
-
}
|
|
330
|
-
// @ts-ignore
|
|
331
|
-
if (task.failed) {
|
|
332
|
-
lastError = task.error
|
|
333
|
-
throw task.error
|
|
334
|
-
}
|
|
335
|
-
const rtnVal = task.result
|
|
336
|
-
// @ts-ignore
|
|
337
|
-
this.emit(Event.Success, rtnVal, this._currentRetries, latency)
|
|
338
|
-
|
|
339
|
-
// Not AwaysTask, we can finish all the retries with success
|
|
340
|
-
if (!AlwaysTask.isAlwaysTask(task)) {
|
|
341
|
-
this._taskingFlag.resolve(rtnVal)
|
|
342
|
-
break
|
|
343
|
-
}
|
|
344
|
-
// AwaysTask, continue to run the task
|
|
345
|
-
} catch (e) {
|
|
346
|
-
// @ts-ignore
|
|
347
|
-
this.emit(Event.Failure, e, this._currentRetries, latency)
|
|
348
|
-
}
|
|
349
|
-
const nextRetries = ++this._currentRetries
|
|
350
|
-
// next retry, max retries reached?
|
|
351
|
-
if (this._currentRetries > this._maxRetries) {
|
|
352
|
-
// @ts-ignore
|
|
353
|
-
this.emit(Event.MaxRetries, nextRetries, this._maxRetries)
|
|
354
|
-
// always task, treat as success, resolve the whole promise with <void>
|
|
355
|
-
if (AlwaysTask.isAlwaysTask(task)) {
|
|
356
|
-
this._taskingFlag.resolve()
|
|
357
|
-
break
|
|
358
|
-
}
|
|
359
|
-
this._taskingFlag.reject(lastError ?? new Error(`Max Retries Exceeded, Retring ${this._currentRetries} times > max ${this._maxRetries}`))
|
|
360
|
-
break
|
|
361
|
-
}
|
|
362
|
-
await PromiseUtils.delay(nextDelay)
|
|
363
|
-
}
|
|
364
|
-
this._taskingFlag.promise.finally(() => {
|
|
365
|
-
this.resetRetryPolicy()
|
|
366
|
-
this._taskingFlag = undefined
|
|
367
|
-
const spent = Date.now() - startAt
|
|
368
|
-
// @ts-ignore
|
|
369
|
-
this.emit(Event.Completed, this._currentRetries, spent)
|
|
370
|
-
})
|
|
371
|
-
return this._taskingFlag.promise
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
/**
|
|
375
|
-
* Stops the retrier with an optional reason. If already stopping, returns the existing break promise.
|
|
376
|
-
* @param {Error} [reason] - Optional reason for stopping (defaults to 'Manually Stop' error).
|
|
377
|
-
* @returns {Promise<void>} A promise that resolves when the retrier has fully stopped.
|
|
378
|
-
*/
|
|
379
|
-
async stop (reason) {
|
|
380
|
-
// @ts-ignore
|
|
381
|
-
this.emit(Event.Stop, reason)
|
|
382
|
-
if (this._taskingFlag == null) {
|
|
383
|
-
return // no task running
|
|
384
|
-
}
|
|
385
|
-
if (this._breakFlag != null) {
|
|
386
|
-
// @ts-ignore
|
|
387
|
-
return this._breakFlag.promise
|
|
388
|
-
}
|
|
389
|
-
this._breakFlag = PromiseUtils.defer()
|
|
390
|
-
this._breakReason = reason ?? new Error('Manually Stop')
|
|
391
|
-
// @ts-ignore
|
|
392
|
-
this.once(Event.Completed, () => {
|
|
393
|
-
// @ts-ignore
|
|
394
|
-
this._breakFlag.resolve()
|
|
395
|
-
})
|
|
396
|
-
|
|
397
|
-
// @ts-ignore
|
|
398
|
-
this._breakFlag.promise.finally(() => {
|
|
399
|
-
this._breakFlag = undefined
|
|
400
|
-
this._breakReason = undefined
|
|
401
|
-
})
|
|
402
|
-
return this._breakFlag.promise
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
/**
|
|
406
|
-
* Resets the retry policy to its initial state.
|
|
407
|
-
*/
|
|
408
|
-
resetRetryPolicy () {
|
|
409
|
-
this._policy.reset()
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* Registers a listener function to be called on "retry" events.
|
|
414
|
-
* @param {Function} listener - The callback function
|
|
415
|
-
* @returns {this}
|
|
416
|
-
*/
|
|
417
|
-
onRetry (listener) {
|
|
418
|
-
// @ts-ignore
|
|
419
|
-
this.on(Event.Retry, listener)
|
|
420
|
-
return this
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
/**
|
|
424
|
-
* Registers a listener for "error" events.
|
|
425
|
-
* @param {Function} listener - The callback function
|
|
426
|
-
* @returns {this}
|
|
427
|
-
*/
|
|
428
|
-
onError (listener) {
|
|
429
|
-
// @ts-ignore
|
|
430
|
-
this.on(Event.Error, listener)
|
|
431
|
-
return this
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
/**
|
|
435
|
-
* Registers a listener for "failure" events.
|
|
436
|
-
* @param {Function} listener - The callback function
|
|
437
|
-
* @returns {this}
|
|
438
|
-
*/
|
|
439
|
-
onFailure (listener) {
|
|
440
|
-
// @ts-ignore
|
|
441
|
-
this.on(Event.Failure, listener)
|
|
442
|
-
return this
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
/**
|
|
446
|
-
* Registers a listener for "success" events.
|
|
447
|
-
* @param {Function} listener - The callback function
|
|
448
|
-
* @returns {this}
|
|
449
|
-
*/
|
|
450
|
-
onSuccess (listener) {
|
|
451
|
-
// @ts-ignore
|
|
452
|
-
this.on(Event.Success, listener)
|
|
453
|
-
return this
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
/**
|
|
457
|
-
* Registers a listener for "start" events.
|
|
458
|
-
* @param {Function} listener - The callback function
|
|
459
|
-
* @returns {this}
|
|
460
|
-
*/
|
|
461
|
-
onStart (listener) {
|
|
462
|
-
// @ts-ignore
|
|
463
|
-
this.on(Event.Start, listener)
|
|
464
|
-
return this
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
/**
|
|
468
|
-
* Registers a listener for "stop" events.
|
|
469
|
-
* @param {Function} listener - The callback function
|
|
470
|
-
* @returns {this}
|
|
471
|
-
*/
|
|
472
|
-
onStop (listener) {
|
|
473
|
-
// @ts-ignore
|
|
474
|
-
this.on(Event.Stop, listener)
|
|
475
|
-
return this
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
/**
|
|
479
|
-
* Registers a listener for "timeout" events.
|
|
480
|
-
* @param {Function} listener - The callback function
|
|
481
|
-
*/
|
|
482
|
-
onTimeout (listener) {
|
|
483
|
-
// @ts-ignore
|
|
484
|
-
this.on(Event.Timeout, listener)
|
|
485
|
-
return this
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
/**
|
|
489
|
-
* Registers a listener for "task-timeout" events.
|
|
490
|
-
* @param {Function} listener - The callback function
|
|
491
|
-
* @returns {this}
|
|
492
|
-
*/
|
|
493
|
-
onTaskTimeout (listener) {
|
|
494
|
-
// @ts-ignore
|
|
495
|
-
this.on(Event.TaskTimeout, listener)
|
|
496
|
-
return this
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
/**
|
|
500
|
-
* Registers a listener for "completed" events.
|
|
501
|
-
* @param {Function} listener - The callback function
|
|
502
|
-
*/
|
|
503
|
-
onCompleted (listener) {
|
|
504
|
-
// @ts-ignore
|
|
505
|
-
this.on(Event.Completed, listener)
|
|
506
|
-
return this
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
/**
|
|
510
|
-
* Registers a listener for the 'MaxRetries' event.
|
|
511
|
-
* @param {Function} listener - The callback function to be executed when max retries are reached.
|
|
512
|
-
* @returns {this}
|
|
513
|
-
*/
|
|
514
|
-
onMaxRetries (listener) {
|
|
515
|
-
// @ts-ignore
|
|
516
|
-
this.on(Event.MaxRetries, listener)
|
|
517
|
-
return this
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
/**
|
|
522
|
-
* Checks if a value represents infinity or a non-positive number.
|
|
523
|
-
* @param {number} value - The value to check
|
|
524
|
-
* @returns {boolean} True if the value is <= 0 or Infinity, false otherwise
|
|
525
|
-
*/
|
|
526
|
-
function isInfinite (value) {
|
|
527
|
-
return value <= 0 || value === Infinity
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
export { Retrier as RetrierType }
|
package/lib/task.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { TypeAssert } from '@creejs/commons-lang'
|
|
2
|
-
// owned
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @typedef {import('./retrier.js').default} Retrier
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
// module vars
|
|
9
|
-
const { assertNotNil, assertFunction } = TypeAssert
|
|
10
|
-
export default class Task {
|
|
11
|
-
/**
|
|
12
|
-
* Creates a new Task instance.
|
|
13
|
-
* @param {Retrier} retrier - The retrier instance.
|
|
14
|
-
* @param {Function} task - The function to be executed as the task.
|
|
15
|
-
*/
|
|
16
|
-
constructor (retrier, task) {
|
|
17
|
-
assertNotNil(retrier, 'retrier')
|
|
18
|
-
assertFunction(task, 'task')
|
|
19
|
-
this.retrier = retrier
|
|
20
|
-
this.task = task
|
|
21
|
-
this.result = undefined
|
|
22
|
-
this.error = undefined
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
get failed () {
|
|
26
|
-
return this.error != null
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
get succeeded () {
|
|
30
|
-
return this.error == null
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Executes the task with the given retry parameters.
|
|
35
|
-
* 1. if execution throw error, keep error in this.error
|
|
36
|
-
* 2. if execution return value, keep it in this.result
|
|
37
|
-
* 3. always return Promise<void>
|
|
38
|
-
* @param {number} retries - The number of retries attempted so far.
|
|
39
|
-
* @param {number} latence - The current latency ms.
|
|
40
|
-
* @param {number} nextInterval - The next interval ms.
|
|
41
|
-
* @returns {Promise<void>} The result of the task execution.
|
|
42
|
-
*/
|
|
43
|
-
async execute (retries, latence, nextInterval) {
|
|
44
|
-
try {
|
|
45
|
-
this.result = await this.task(retries, latence, nextInterval)
|
|
46
|
-
this.error = undefined
|
|
47
|
-
} catch (e) {
|
|
48
|
-
this.error = e
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
dispose () {
|
|
53
|
-
// @ts-ignore
|
|
54
|
-
this.retrier = undefined
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export { Task as TaskType }
|