18
18
19
19
const MinimumBackoffInMs = 30 * 1000 ; // 30s
20
20
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.
22
22
const JitterRatio = 0.25 ;
23
23
24
24
export class RefreshTimer {
@@ -41,13 +41,13 @@ export class RefreshTimer {
41
41
}
42
42
43
43
public backoff ( ) : void {
44
- this . _backoffEnd = Date . now ( ) + this . _calculateBackoffTime ( ) ;
45
44
this . _failedAttempts += 1 ;
45
+ this . _backoffEnd = Date . now ( ) + this . _calculateBackoffTime ( ) ;
46
46
}
47
47
48
48
public reset ( ) : void {
49
- this . _backoffEnd = Date . now ( ) + this . _interval ;
50
49
this . _failedAttempts = 0 ;
50
+ this . _backoffEnd = Date . now ( ) + this . _interval ;
51
51
}
52
52
53
53
private _calculateBackoffTime ( ) : number {
@@ -66,9 +66,9 @@ export class RefreshTimer {
66
66
maxBackoffMs = this . _maxBackoff ;
67
67
}
68
68
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 ) ;
72
72
if ( calculatedBackoffMs > maxBackoffMs ) {
73
73
calculatedBackoffMs = maxBackoffMs ;
74
74
}
@@ -80,24 +80,3 @@ export class RefreshTimer {
80
80
}
81
81
82
82
}
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