@@ -180,10 +180,16 @@ export default class Sarus {
180
180
* after the constructor wraps up.
181
181
*/
182
182
state :
183
- | { kind : "connecting" }
183
+ | { kind : "connecting" ; failedConnectionAttempts : number }
184
184
| { kind : "connected" }
185
185
| { kind : "disconnected" }
186
- | { kind : "closed" } = { kind : "connecting" } ;
186
+ /**
187
+ * The closed state carries of the number of failed connection attempts
188
+ */
189
+ | { kind : "closed" ; failedConnectionAttempts : number } = {
190
+ kind : "connecting" ,
191
+ failedConnectionAttempts : 0 ,
192
+ } ;
187
193
188
194
constructor ( props : SarusClassParams ) {
189
195
// Extract the properties that are passed to the class
@@ -378,7 +384,19 @@ export default class Sarus {
378
384
* Connects the WebSocket client, and attaches event listeners
379
385
*/
380
386
connect ( ) {
381
- this . state = { kind : "connecting" } ;
387
+ if ( this . state . kind === "closed" ) {
388
+ this . state = {
389
+ kind : "connecting" ,
390
+ failedConnectionAttempts : this . state . failedConnectionAttempts ,
391
+ } ;
392
+ } else if (
393
+ this . state . kind === "connected" ||
394
+ this . state . kind === "disconnected"
395
+ ) {
396
+ this . state = { kind : "connecting" , failedConnectionAttempts : 0 } ;
397
+ } else {
398
+ // This is a NOOP, we are already connecting
399
+ }
382
400
this . ws = new WebSocket ( this . url , this . protocols ) ;
383
401
this . setBinaryType ( ) ;
384
402
this . attachEventListeners ( ) ;
@@ -392,11 +410,22 @@ export default class Sarus {
392
410
reconnect ( ) {
393
411
const self = this ;
394
412
const { retryConnectionDelay, exponentialBackoff } = self ;
413
+ // If we are already in a "connecting" state, we need to refer to the
414
+ // current amount of connection attemps to correctly calculate the
415
+ // exponential delay -- if exponential backoff is enabled.
416
+ const failedConnectionAttempts =
417
+ self . state . kind === "connecting"
418
+ ? self . state . failedConnectionAttempts
419
+ : 0 ;
395
420
396
421
// If no exponential backoff is enabled, retryConnectionDelay will
397
422
// be scaled by a factor of 1 and it will stay the original value.
398
423
const delay = exponentialBackoff
399
- ? calculateRetryDelayFactor ( exponentialBackoff , retryConnectionDelay , 0 )
424
+ ? calculateRetryDelayFactor (
425
+ exponentialBackoff ,
426
+ retryConnectionDelay ,
427
+ failedConnectionAttempts ,
428
+ )
400
429
: retryConnectionDelay ;
401
430
402
431
setTimeout ( self . connect , delay ) ;
@@ -544,7 +573,22 @@ export default class Sarus {
544
573
if ( eventName === "open" ) {
545
574
self . state = { kind : "connected" } ;
546
575
} else if ( eventName === "close" && self . reconnectAutomatically ) {
547
- self . state = { kind : "closed" } ;
576
+ const { state } = self ;
577
+ // If we have previously been "connecting", we carry over the amount
578
+ // of failed connection attempts and add 1, since the current
579
+ // connection attempt failed. We stay "connecting" instead of
580
+ // "closed", since we've never been fully "connected" in the first
581
+ // place.
582
+ if ( state . kind === "connecting" ) {
583
+ self . state = {
584
+ kind : "connecting" ,
585
+ failedConnectionAttempts : state . failedConnectionAttempts + 1 ,
586
+ } ;
587
+ } else {
588
+ // If we were in a different state, we assume that our connection
589
+ // freshly closed and have not made any failed connection attempts.
590
+ self . state = { kind : "closed" , failedConnectionAttempts : 0 } ;
591
+ }
548
592
self . removeEventListeners ( ) ;
549
593
self . reconnect ( ) ;
550
594
}
0 commit comments