Skip to content

Commit 98b12e2

Browse files
committed
limit max exponential to 30 and remove utils no longer needed
1 parent 1099ec7 commit 98b12e2

File tree

1 file changed

+6
-27
lines changed

1 file changed

+6
-27
lines changed

src/refresh/RefreshTimer.ts

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
const MinimumBackoffInMs = 30 * 1000; // 30s
2020
const MaximumBackoffInMs = 10 * 60 * 1000; // 10min
21-
const MaxSafeExponential = 53; // Used to avoid overflow, as Number.MAX_SAFE_INTEGER = 2^53 - 1.
21+
const MaxSafeExponential = 30; // Used to avoid overflow. bitwise operations in JavaScript are limited to 32 bits. It overflows at 2^31 - 1.
2222
const JitterRatio = 0.25;
2323

2424
export class RefreshTimer {
@@ -41,13 +41,13 @@ export class RefreshTimer {
4141
}
4242

4343
public backoff(): void {
44-
this._backoffEnd = Date.now() + this._calculateBackoffTime();
4544
this._failedAttempts += 1;
45+
this._backoffEnd = Date.now() + this._calculateBackoffTime();
4646
}
4747

4848
public reset(): void {
49-
this._backoffEnd = Date.now() + this._interval;
5049
this._failedAttempts = 0;
50+
this._backoffEnd = Date.now() + this._interval;
5151
}
5252

5353
private _calculateBackoffTime(): number {
@@ -66,9 +66,9 @@ export class RefreshTimer {
6666
maxBackoffMs = this._maxBackoff;
6767
}
6868

69-
// exponential: minBackoffMs * 2^failedAttempts
70-
const exponential = Math.min(this._failedAttempts, MaxSafeExponential);
71-
let calculatedBackoffMs = minBackoffMs * (efficientPowerOfTwo(exponential));
69+
// exponential: minBackoffMs * 2^(failedAttempts-1)
70+
const exponential = Math.min(this._failedAttempts - 1, MaxSafeExponential);
71+
let calculatedBackoffMs = minBackoffMs * (1 << exponential);
7272
if (calculatedBackoffMs > maxBackoffMs) {
7373
calculatedBackoffMs = maxBackoffMs;
7474
}
@@ -80,24 +80,3 @@ export class RefreshTimer {
8080
}
8181

8282
}
83-
84-
/**
85-
* Efficient way to calculate 2^exponential.
86-
*
87-
* `Math.pow(base, exp)` is not used because it is less efficient and accurate by operating floating-point number.
88-
* `1 << exp` is not used because it returns wrong results when exp >= 31.
89-
*/
90-
function efficientPowerOfTwo(positiveExponential: number) {
91-
if (positiveExponential < 0) {
92-
throw new Error("exponential must be a non-negative integer.");
93-
} else if (positiveExponential > MaxSafeExponential) {
94-
throw new Error(`exponential must be less than or equal to ${MaxSafeExponential}.`);
95-
}
96-
97-
// bitwise operations in JavaScript are limited to 32 bits. It overflows at 2^31 - 1.
98-
if (positiveExponential <= 30) {
99-
return 1 << positiveExponential;
100-
} else {
101-
return (1 << 30) * (1 << (positiveExponential - 30));
102-
}
103-
}

0 commit comments

Comments
 (0)