@@ -2770,16 +2770,34 @@ where
2770
2770
return Poll :: Ready ( Ok ( ( ) ) ) ;
2771
2771
}
2772
2772
}
2773
- Some ( Err ( _) ) => {
2774
- // Task panicked or was cancelled
2775
- trace ! ( "Slot refresh task panicked or was cancelled" ) ;
2776
- let new_handle = Self :: spawn_refresh_slots_task (
2777
- self . inner . clone ( ) ,
2778
- & RefreshPolicy :: Throttable ,
2779
- ) ;
2780
- self . state =
2781
- ConnectionState :: Recover ( RecoverFuture :: RefreshingSlots ( new_handle) ) ;
2782
- return Poll :: Ready ( Ok ( ( ) ) ) ;
2773
+ Some ( Err ( join_err) ) => {
2774
+ if join_err. is_cancelled ( ) {
2775
+ // Task was intentionally aborted - don't treat as an error
2776
+ trace ! ( "Slot refresh task was aborted" ) ;
2777
+ self . state = ConnectionState :: PollComplete ;
2778
+ return Poll :: Ready ( Ok ( ( ) ) ) ;
2779
+ } else {
2780
+ // Task panicked - try reconnecting to initial nodes as a recovery strategy
2781
+ warn ! ( "Slot refresh task panicked: {:?} - attempting recovery by reconnecting to initial nodes" , join_err) ;
2782
+
2783
+ // TODO - consider a gracefully closing of the client
2784
+ // Since a panic indicates a bug in the refresh logic,
2785
+ // it might be safer to close the client entirely
2786
+ self . state =
2787
+ ConnectionState :: Recover ( RecoverFuture :: ReconnectToInitialNodes (
2788
+ Box :: pin ( ClusterConnInner :: reconnect_to_initial_nodes (
2789
+ self . inner . clone ( ) ,
2790
+ ) ) ,
2791
+ ) ) ;
2792
+
2793
+ // Report this critical error to clients
2794
+ let err = RedisError :: from ( (
2795
+ ErrorKind :: ClientError ,
2796
+ "Slot refresh task panicked" ,
2797
+ format ! ( "{:?}" , join_err) ,
2798
+ ) ) ;
2799
+ return Poll :: Ready ( Err ( err) ) ;
2800
+ }
2783
2801
}
2784
2802
None => {
2785
2803
// Task is still running
0 commit comments