1818
1919const MinimumBackoffInMs = 30 * 1000 ; // 30s
2020const 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.
2222const JitterRatio = 0.25 ;
2323
2424export 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