@@ -20,7 +20,7 @@ use itertools::Itertools;
2020use scylla_cql:: errors:: { BadQuery , NewSessionError } ;
2121use scylla_cql:: frame:: response:: result:: TableSpec ;
2222use scylla_cql:: types:: serialize:: row:: SerializedValues ;
23- use std:: collections:: HashMap ;
23+ use std:: collections:: { HashMap , HashSet } ;
2424use std:: net:: SocketAddr ;
2525use std:: sync:: Arc ;
2626use std:: time:: Duration ;
@@ -285,7 +285,7 @@ impl ClusterData {
285285 known_peers : & HashMap < Uuid , Arc < Node > > ,
286286 used_keyspace : & Option < VerifiedKeyspaceName > ,
287287 host_filter : Option < & dyn HostFilter > ,
288- tablets : TabletsInfo ,
288+ mut tablets : TabletsInfo ,
289289 ) -> Self {
290290 // Create new updated known_peers and ring
291291 let mut new_known_peers: HashMap < Uuid , Arc < Node > > =
@@ -345,6 +345,47 @@ impl ClusterData {
345345 }
346346 }
347347
348+ {
349+ let removed_nodes = {
350+ let mut removed_nodes = HashSet :: new ( ) ;
351+ for old_peer in known_peers {
352+ if !new_known_peers. contains_key ( old_peer. 0 ) {
353+ removed_nodes. insert ( * old_peer. 0 ) ;
354+ }
355+ }
356+
357+ removed_nodes
358+ } ;
359+
360+ let table_predicate = |spec : & TableSpec | {
361+ if let Some ( ks) = metadata. keyspaces . get ( spec. ks_name ( ) ) {
362+ ks. tables . contains_key ( spec. table_name ( ) )
363+ } else {
364+ false
365+ }
366+ } ;
367+
368+ let recreated_nodes = {
369+ let mut recreated_nodes = HashMap :: new ( ) ;
370+ for ( old_peer_id, old_peer_node) in known_peers {
371+ if let Some ( new_peer_node) = new_known_peers. get ( old_peer_id) {
372+ if !Arc :: ptr_eq ( old_peer_node, new_peer_node) {
373+ recreated_nodes. insert ( * old_peer_id, Arc :: clone ( new_peer_node) ) ;
374+ }
375+ }
376+ }
377+
378+ recreated_nodes
379+ } ;
380+
381+ tablets. perform_maintenance (
382+ & table_predicate,
383+ & removed_nodes,
384+ & new_known_peers,
385+ & recreated_nodes,
386+ )
387+ }
388+
348389 Self :: update_rack_count ( & mut datacenters) ;
349390
350391 let keyspaces = metadata. keyspaces ;
@@ -491,7 +532,22 @@ impl ClusterData {
491532 let replica_translator = |uuid : Uuid | self . known_peers . get ( & uuid) . cloned ( ) ;
492533
493534 for ( table, raw_tablet) in raw_tablets. into_iter ( ) {
494- let tablet = Tablet :: from_raw_tablet ( & raw_tablet, replica_translator) ;
535+ // Should we skip tablets that belong to a keyspace not present in
536+ // self.keyspaces? The keyspace could have been, without driver's knowledge:
537+ // 1. Dropped - in which case we'll remove its info soon (when refreshing
538+ // topology) anyway.
539+ // 2. Created - no harm in storing the info now.
540+ //
541+ // So I think we can safely skip checking keyspace presence.
542+ let tablet = match Tablet :: from_raw_tablet ( raw_tablet, replica_translator) {
543+ Ok ( t) => t,
544+ Err ( ( t, f) ) => {
545+ debug ! ( "Nodes ({}) that are replicas for a tablet {{ks: {}, table: {}, range: [{}. {}]}} not present in current ClusterData.known_peers. \
546+ Skipping these replicas until topology refresh",
547+ f. iter( ) . format( ", " ) , table. ks_name( ) , table. table_name( ) , t. range( ) . 0 . value( ) , t. range( ) . 1 . value( ) ) ;
548+ t
549+ }
550+ } ;
495551 self . locator . tablets . add_tablet ( table, tablet) ;
496552 }
497553 }
0 commit comments