-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathBackoff.ts
More file actions
51 lines (42 loc) · 1.36 KB
/
Backoff.ts
File metadata and controls
51 lines (42 loc) · 1.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
export class Backoff {
// For testing purposes, assign to overwrite the provided value by param
static __TEST__BASE_MILLIS?: number;
static __TEST__MAX_MILLIS?: number;
static DEFAULT_BASE_MILLIS = 1000; // 1 second
static DEFAULT_MAX_MILLIS = 1800000; // 30 minutes
baseMillis: number;
maxMillis: number;
attempts: number;
cb: (...args: any[]) => any;
timeoutID: ReturnType<typeof setTimeout> | undefined;
/**
* Schedule function calls with exponential backoff
*/
constructor(cb: (...args: any[]) => any, baseMillis?: number, maxMillis?: number) {
this.baseMillis = Backoff.__TEST__BASE_MILLIS || baseMillis || Backoff.DEFAULT_BASE_MILLIS;
this.maxMillis = Backoff.__TEST__MAX_MILLIS || maxMillis || Backoff.DEFAULT_MAX_MILLIS;
this.attempts = 0;
this.cb = cb;
}
/**
* Schedule a next call to `cb`
* @returns scheduled delay in milliseconds
*/
scheduleCall() {
let delayInMillis = Math.min(this.baseMillis * Math.pow(2, this.attempts), this.maxMillis);
if (this.timeoutID) clearTimeout(this.timeoutID);
this.timeoutID = setTimeout(() => {
this.timeoutID = undefined;
this.cb();
}, delayInMillis);
this.attempts++;
return delayInMillis;
}
reset() {
this.attempts = 0;
if (this.timeoutID) {
clearTimeout(this.timeoutID);
this.timeoutID = undefined;
}
}
}