@@ -97,6 +97,8 @@ use backoff_tokio::future::retry;
97
97
use backoff_tokio:: { Error as BackoffError , ExponentialBackoff } ;
98
98
#[ cfg( feature = "tokio-comp" ) ]
99
99
use tokio:: { sync:: Notify , time:: timeout} ;
100
+ #[ cfg( feature = "tokio-comp" ) ]
101
+ use async_trait:: async_trait;
100
102
101
103
use dispose:: { Disposable , Dispose } ;
102
104
use futures:: { future:: BoxFuture , prelude:: * , ready} ;
@@ -379,20 +381,37 @@ where
379
381
#[ cfg( feature = "tokio-comp" ) ]
380
382
#[ derive( Clone ) ]
381
383
struct TokioDisconnectNotifier {
382
- pub disconnect_notifier : Arc < Notify > ,
384
+ disconnect_notifier : Arc < Notify > ,
383
385
}
384
386
385
387
#[ cfg( feature = "tokio-comp" ) ]
388
+ #[ async_trait]
386
389
impl DisconnectNotifier for TokioDisconnectNotifier {
387
390
fn notify_disconnect ( & mut self ) {
388
391
self . disconnect_notifier . notify_one ( ) ;
389
392
}
390
393
394
+ async fn wait_for_disconnect_with_timeout ( & self , max_wait : & Duration ) {
395
+ let _ = timeout ( * max_wait, async {
396
+ self . disconnect_notifier . notified ( ) . await ;
397
+ } )
398
+ . await ;
399
+ }
400
+
391
401
fn clone_box ( & self ) -> Box < dyn DisconnectNotifier > {
392
402
Box :: new ( self . clone ( ) )
393
403
}
394
404
}
395
405
406
+ #[ cfg( feature = "tokio-comp" ) ]
407
+ impl TokioDisconnectNotifier {
408
+ fn new ( ) -> TokioDisconnectNotifier {
409
+ TokioDisconnectNotifier {
410
+ disconnect_notifier : Arc :: new ( Notify :: new ( ) ) ,
411
+ }
412
+ }
413
+ }
414
+
396
415
type ConnectionMap < C > = connections_container:: ConnectionsMap < ConnectionFuture < C > > ;
397
416
type ConnectionsContainer < C > =
398
417
self :: connections_container:: ConnectionsContainer < ConnectionFuture < C > > ;
@@ -406,8 +425,6 @@ pub(crate) struct InnerCore<C> {
406
425
subscriptions_by_address : RwLock < HashMap < String , PubSubSubscriptionInfo > > ,
407
426
unassigned_subscriptions : RwLock < PubSubSubscriptionInfo > ,
408
427
glide_connection_options : GlideConnectionOptions ,
409
- #[ cfg( feature = "tokio-comp" ) ]
410
- tokio_notify : Arc < Notify > ,
411
428
}
412
429
413
430
pub ( crate ) type Core < C > = Arc < InnerCore < C > > ;
@@ -990,27 +1007,24 @@ where
990
1007
cluster_params : ClusterParams ,
991
1008
push_sender : Option < mpsc:: UnboundedSender < PushInfo > > ,
992
1009
) -> RedisResult < Disposable < Self > > {
993
- #[ cfg( feature = "tokio-comp" ) ]
994
- let tokio_notify = Arc :: new ( Notify :: new ( ) ) ;
995
-
996
1010
let disconnect_notifier = {
997
1011
#[ cfg( feature = "tokio-comp" ) ]
998
1012
{
999
- Some :: < Box < dyn DisconnectNotifier > > ( Box :: new ( TokioDisconnectNotifier {
1000
- disconnect_notifier : tokio_notify. clone ( ) ,
1001
- } ) )
1013
+ Some :: < Box < dyn DisconnectNotifier > > ( Box :: new ( TokioDisconnectNotifier :: new ( ) ) )
1002
1014
}
1003
1015
#[ cfg( not( feature = "tokio-comp" ) ) ]
1004
1016
None
1005
1017
} ;
1006
1018
1019
+ let glide_connection_options = GlideConnectionOptions {
1020
+ push_sender,
1021
+ disconnect_notifier,
1022
+ } ;
1023
+
1007
1024
let connections = Self :: create_initial_connections (
1008
1025
initial_nodes,
1009
1026
& cluster_params,
1010
- GlideConnectionOptions {
1011
- push_sender : push_sender. clone ( ) ,
1012
- disconnect_notifier : disconnect_notifier. clone ( ) ,
1013
- } ,
1027
+ glide_connection_options. clone ( ) ,
1014
1028
)
1015
1029
. await ?;
1016
1030
@@ -1035,12 +1049,7 @@ where
1035
1049
} ,
1036
1050
) ,
1037
1051
subscriptions_by_address : RwLock :: new ( Default :: default ( ) ) ,
1038
- glide_connection_options : GlideConnectionOptions {
1039
- push_sender : push_sender. clone ( ) ,
1040
- disconnect_notifier : disconnect_notifier. clone ( ) ,
1041
- } ,
1042
- #[ cfg( feature = "tokio-comp" ) ]
1043
- tokio_notify,
1052
+ glide_connection_options,
1044
1053
} ) ;
1045
1054
let mut connection = ClusterConnInner {
1046
1055
inner,
@@ -1227,40 +1236,40 @@ where
1227
1236
// In addition, the validation is done by peeking at the state of the underlying transport w/o overhead of additional commands to server.
1228
1237
async fn validate_all_user_connections ( inner : Arc < InnerCore < C > > ) {
1229
1238
let mut all_valid_conns = HashMap :: new ( ) ;
1230
- let mut all_nodes_with_slots = HashSet :: new ( ) ;
1231
1239
// prep connections and clean out these w/o assigned slots, as we might have established connections to unwanted hosts
1232
- {
1233
- let mut nodes_to_delete = Vec :: new ( ) ;
1234
- let connections_container = inner. conn_lock . read ( ) . await ;
1235
-
1236
- connections_container
1237
- . slot_map
1238
- . addresses_for_all_nodes ( )
1239
- . iter ( )
1240
- . for_each ( |addr| {
1241
- all_nodes_with_slots. insert ( String :: from ( * addr) ) ;
1242
- } ) ;
1240
+ let mut nodes_to_delete = Vec :: new ( ) ;
1241
+ let connections_container = inner. conn_lock . read ( ) . await ;
1243
1242
1244
- connections_container
1245
- . all_node_connections ( )
1246
- . for_each ( |( addr, con) | {
1247
- if all_nodes_with_slots. contains ( & addr) {
1248
- all_valid_conns. insert ( addr. clone ( ) , con. clone ( ) ) ;
1249
- } else {
1250
- nodes_to_delete. push ( addr. clone ( ) ) ;
1251
- }
1252
- } ) ;
1243
+ let all_nodes_with_slots: HashSet < String > = connections_container
1244
+ . slot_map
1245
+ . addresses_for_all_nodes ( )
1246
+ . iter ( )
1247
+ . map ( |addr| String :: from ( * addr) )
1248
+ . collect ( ) ;
1249
+
1250
+ connections_container
1251
+ . all_node_connections ( )
1252
+ . for_each ( |( addr, con) | {
1253
+ if all_nodes_with_slots. contains ( & addr) {
1254
+ all_valid_conns. insert ( addr. clone ( ) , con. clone ( ) ) ;
1255
+ } else {
1256
+ nodes_to_delete. push ( addr. clone ( ) ) ;
1257
+ }
1258
+ } ) ;
1253
1259
1254
- for addr in & nodes_to_delete {
1255
- connections_container. remove_node ( addr) ;
1256
- }
1260
+ for addr in & nodes_to_delete {
1261
+ connections_container. remove_node ( addr) ;
1257
1262
}
1258
1263
1264
+ drop ( connections_container) ;
1265
+
1259
1266
// identify nodes with closed connection
1260
1267
let mut addrs_to_refresh = Vec :: new ( ) ;
1261
1268
for ( addr, con_fut) in & all_valid_conns {
1262
1269
let con = con_fut. clone ( ) . await ;
1270
+ // connection object might be present despite the transport being closed
1263
1271
if con. is_closed ( ) {
1272
+ // transport is closed, need to refresh
1264
1273
addrs_to_refresh. push ( addr. clone ( ) ) ;
1265
1274
}
1266
1275
}
@@ -1289,7 +1298,7 @@ where
1289
1298
inner : Arc < InnerCore < C > > ,
1290
1299
addresses : Vec < String > ,
1291
1300
conn_type : RefreshConnectionType ,
1292
- try_existing_node : bool ,
1301
+ check_existing_conn : bool ,
1293
1302
) {
1294
1303
info ! ( "Started refreshing connections to {:?}" , addresses) ;
1295
1304
let connections_container = inner. conn_lock . read ( ) . await ;
@@ -1301,10 +1310,10 @@ where
1301
1310
. fold (
1302
1311
& * connections_container,
1303
1312
|connections_container, address| async move {
1304
- let node_option = if try_existing_node {
1313
+ let node_option = if check_existing_conn {
1305
1314
connections_container. remove_node ( & address)
1306
1315
} else {
1307
- Option :: None
1316
+ None
1308
1317
} ;
1309
1318
1310
1319
// override subscriptions for this connection
@@ -1541,13 +1550,15 @@ where
1541
1550
1542
1551
async fn connections_validation_task ( inner : Arc < InnerCore < C > > , interval_duration : Duration ) {
1543
1552
loop {
1544
- #[ cfg( feature = "tokio-comp" ) ]
1545
- let _ = timeout ( interval_duration, async {
1546
- inner. tokio_notify . notified ( ) . await ;
1547
- } )
1548
- . await ;
1549
- #[ cfg( not( feature = "tokio-comp" ) ) ]
1550
- let _ = boxed_sleep ( interval_duration) . await ;
1553
+ if let Some ( disconnect_notifier) =
1554
+ inner. glide_connection_options . disconnect_notifier . clone ( )
1555
+ {
1556
+ disconnect_notifier
1557
+ . wait_for_disconnect_with_timeout ( & interval_duration)
1558
+ . await ;
1559
+ } else {
1560
+ let _ = boxed_sleep ( interval_duration) . await ;
1561
+ }
1551
1562
1552
1563
Self :: validate_all_user_connections ( inner. clone ( ) ) . await ;
1553
1564
}
0 commit comments