@@ -47,6 +47,7 @@ internal sealed class PhysicalBridge : IDisposable
4747 private int beating ;
4848 private int failConnectCount = 0 ;
4949 private volatile bool isDisposed ;
50+ private volatile bool shouldResetConnectionRetryCount ;
5051 private long nonPreferredEndpointCount ;
5152
5253 // private volatile int missedHeartbeats;
@@ -597,6 +598,8 @@ internal void OnHeartbeat(bool ifConnectedOnly)
597598 // We need to time that out and cleanup the PhysicalConnection if needed, otherwise that reader and socket will remain open
598599 // for the lifetime of the application due to being orphaned, yet still referenced by the active task doing the pipe read.
599600 case ( int ) State . ConnectedEstablished :
601+ // Track that we should reset the count on the next disconnect, but not do so in a loop
602+ shouldResetConnectionRetryCount = true ;
600603 var tmp = physical ;
601604 if ( tmp != null )
602605 {
@@ -668,7 +671,14 @@ internal void OnHeartbeat(bool ifConnectedOnly)
668671 }
669672 break ;
670673 case ( int ) State . Disconnected :
671- Interlocked . Exchange ( ref connectTimeoutRetryCount , 0 ) ;
674+ // Only if we should reset the connection count
675+ // This should only happen after a successful reconnection, and not every time we bounce from BeginConnectAsync -> Disconnected
676+ // in a failure loop case that happens when a node goes missing forever.
677+ if ( shouldResetConnectionRetryCount )
678+ {
679+ shouldResetConnectionRetryCount = false ;
680+ Interlocked . Exchange ( ref connectTimeoutRetryCount , 0 ) ;
681+ }
672682 if ( ! ifConnectedOnly )
673683 {
674684 Multiplexer . Trace ( "Resurrecting " + ToString ( ) ) ;
0 commit comments