Skip to content

Commit 800aabc

Browse files
committed
Move handling of MissingUserDefinedType to ClusterData::new
This commit changes type of `keyspaces` field in `Metadata` from `HashMap<String, Keyspace>` to `HashMap<String, Result<Keyspace, MissingUserDefinedType>>`. Because of that, it also removed `MissingUserDefinedType` handling from `query_metadata`. Now handling this error is done in `ClusterData::new`. This has an advantage: we can use older version of the keyspace metadata if the new version has this error.
1 parent 82561f1 commit 800aabc

File tree

7 files changed

+86
-33
lines changed

7 files changed

+86
-33
lines changed

scylla/src/cluster/metadata.rs

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ pub(crate) struct MetadataReader {
8787
/// Describes all metadata retrieved from the cluster
8888
pub(crate) struct Metadata {
8989
pub(crate) peers: Vec<Peer>,
90-
pub(crate) keyspaces: HashMap<String, Keyspace>,
90+
pub(crate) keyspaces: HashMap<String, Result<Keyspace, MissingUserDefinedType>>,
9191
}
9292

9393
#[non_exhaustive] // <- so that we can add more fields in a backwards-compatible way
@@ -297,7 +297,7 @@ pub struct UserDefinedType {
297297
/// Represents a user defined type whose definition is missing from the metadata.
298298
#[derive(Clone, Debug, Error)]
299299
#[error("Missing UDT: {keyspace}, {name}")]
300-
struct MissingUserDefinedType {
300+
pub(crate) struct MissingUserDefinedType {
301301
name: String,
302302
keyspace: String,
303303
}
@@ -800,17 +800,6 @@ async fn query_metadata(
800800
return Err(MetadataError::Peers(PeersMetadataError::EmptyTokenLists).into());
801801
}
802802

803-
let keyspaces = keyspaces
804-
.into_iter()
805-
.filter_map(|(ks_name, ks)| match ks {
806-
Ok(ks) => Some((ks_name, ks)),
807-
Err(e) => {
808-
warn!("Error while processing keyspace \"{ks_name}\": {e}");
809-
None
810-
}
811-
})
812-
.collect();
813-
814803
Ok(Metadata { peers, keyspaces })
815804
}
816805

scylla/src/cluster/state.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use scylla_cql::frame::response::result::TableSpec;
1212
use scylla_cql::types::serialize::row::SerializedValues;
1313
use std::collections::{HashMap, HashSet};
1414
use std::sync::Arc;
15-
use tracing::debug;
15+
use tracing::{debug, warn};
1616
use uuid::Uuid;
1717

1818
use super::metadata::{Keyspace, Metadata, Strategy};
@@ -64,6 +64,7 @@ impl ClusterState {
6464
used_keyspace: &Option<VerifiedKeyspaceName>,
6565
host_filter: Option<&dyn HostFilter>,
6666
mut tablets: TabletsInfo,
67+
old_keyspaces: &HashMap<String, Keyspace>,
6768
) -> Self {
6869
// Create new updated known_peers and ring
6970
let mut new_known_peers: HashMap<Uuid, Arc<Node>> =
@@ -109,6 +110,26 @@ impl ClusterState {
109110
}
110111
}
111112

113+
let keyspaces: HashMap<String, Keyspace> = metadata
114+
.keyspaces
115+
.into_iter()
116+
.filter_map(|(ks_name, ks)| match ks {
117+
Ok(ks) => Some((ks_name, ks)),
118+
Err(e) => {
119+
if let Some(old_ks) = old_keyspaces.get(&ks_name) {
120+
warn!("Encountered an error while processing metadata of keyspace \"{ks_name}\": {e}.\
121+
Re-using older version of this keyspace metadata");
122+
Some((ks_name, old_ks.clone()))
123+
} else {
124+
warn!("Encountered an error while processing metadata of keyspace \"{ks_name}\": {e}.\
125+
No previous version of this keyspace metadata found, so it will not be\
126+
present in ClusterData until next refresh.");
127+
None
128+
}
129+
}
130+
})
131+
.collect();
132+
112133
{
113134
let removed_nodes = {
114135
let mut removed_nodes = HashSet::new();
@@ -122,7 +143,7 @@ impl ClusterState {
122143
};
123144

124145
let table_predicate = |spec: &TableSpec| {
125-
if let Some(ks) = metadata.keyspaces.get(spec.ks_name()) {
146+
if let Some(ks) = keyspaces.get(spec.ks_name()) {
126147
ks.tables.contains_key(spec.table_name())
127148
} else {
128149
false
@@ -150,7 +171,6 @@ impl ClusterState {
150171
)
151172
}
152173

153-
let keyspaces = metadata.keyspaces;
154174
let (locator, keyspaces) = tokio::task::spawn_blocking(move || {
155175
let keyspace_strategies = keyspaces.values().map(|ks| &ks.strategy);
156176
let locator = ReplicaLocator::new(ring.into_iter(), keyspace_strategies, tablets);

scylla/src/cluster/worker.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ impl Cluster {
140140
&None,
141141
host_filter.as_deref(),
142142
TabletsInfo::new(),
143+
&HashMap::new(),
143144
)
144145
.await;
145146
cluster_data.wait_until_all_pools_are_initialized().await;
@@ -413,6 +414,7 @@ impl ClusterWorker {
413414
&self.used_keyspace,
414415
self.host_filter.as_deref(),
415416
cluster_data.locator.tablets.clone(),
417+
&cluster_data.keyspaces,
416418
)
417419
.await,
418420
);

scylla/src/policies/load_balancing/default.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,6 +1419,7 @@ mod tests {
14191419
&None,
14201420
None,
14211421
TabletsInfo::new(),
1422+
&HashMap::new(),
14221423
)
14231424
.await
14241425
}
@@ -1449,6 +1450,7 @@ mod tests {
14491450
&None,
14501451
None,
14511452
TabletsInfo::new(),
1453+
&HashMap::new(),
14521454
)
14531455
.await
14541456
}
@@ -2498,6 +2500,7 @@ mod tests {
24982500
Some(&FHostFilter)
24992501
},
25002502
TabletsInfo::new(),
2503+
&HashMap::new(),
25012504
)
25022505
.await;
25032506

scylla/src/routing/locator/mod.rs

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -860,43 +860,79 @@ mod tests {
860860
check(
861861
160,
862862
None,
863-
&metadata.keyspaces.get(KEYSPACE_NTS_RF_3).unwrap().strategy,
863+
&metadata
864+
.keyspaces
865+
.get(KEYSPACE_NTS_RF_3)
866+
.unwrap()
867+
.as_ref()
868+
.unwrap()
869+
.strategy,
864870
TABLE_NTS_RF_3,
865871
vec![F, A, C, D, G, E],
866872
);
867873
check(
868874
160,
869875
None,
870-
&metadata.keyspaces.get(KEYSPACE_NTS_RF_2).unwrap().strategy,
876+
&metadata
877+
.keyspaces
878+
.get(KEYSPACE_NTS_RF_2)
879+
.unwrap()
880+
.as_ref()
881+
.unwrap()
882+
.strategy,
871883
TABLE_NTS_RF_2,
872884
vec![F, A, D, G],
873885
);
874886
check(
875887
160,
876888
None,
877-
&metadata.keyspaces.get(KEYSPACE_SS_RF_2).unwrap().strategy,
889+
&metadata
890+
.keyspaces
891+
.get(KEYSPACE_SS_RF_2)
892+
.unwrap()
893+
.as_ref()
894+
.unwrap()
895+
.strategy,
878896
TABLE_SS_RF_2,
879897
vec![F, A],
880898
);
881899

882900
check(
883901
160,
884902
Some("eu"),
885-
&metadata.keyspaces.get(KEYSPACE_NTS_RF_3).unwrap().strategy,
903+
&metadata
904+
.keyspaces
905+
.get(KEYSPACE_NTS_RF_3)
906+
.unwrap()
907+
.as_ref()
908+
.unwrap()
909+
.strategy,
886910
TABLE_NTS_RF_3,
887911
vec![A, C, G],
888912
);
889913
check(
890914
160,
891915
Some("us"),
892-
&metadata.keyspaces.get(KEYSPACE_NTS_RF_3).unwrap().strategy,
916+
&metadata
917+
.keyspaces
918+
.get(KEYSPACE_NTS_RF_3)
919+
.unwrap()
920+
.as_ref()
921+
.unwrap()
922+
.strategy,
893923
TABLE_NTS_RF_3,
894924
vec![F, D, E],
895925
);
896926
check(
897927
160,
898928
Some("eu"),
899-
&metadata.keyspaces.get(KEYSPACE_SS_RF_2).unwrap().strategy,
929+
&metadata
930+
.keyspaces
931+
.get(KEYSPACE_SS_RF_2)
932+
.unwrap()
933+
.as_ref()
934+
.unwrap()
935+
.strategy,
900936
TABLE_SS_RF_2,
901937
vec![A],
902938
);

scylla/src/routing/locator/precomputed_replicas.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,14 +231,14 @@ mod tests {
231231
let mut metadata = mock_metadata_for_token_aware_tests();
232232
metadata.keyspaces = [(
233233
"SimpleStrategy{rf=2}".into(),
234-
Keyspace {
234+
Ok(Keyspace {
235235
strategy: Strategy::SimpleStrategy {
236236
replication_factor: 2,
237237
},
238238
tables: HashMap::new(),
239239
views: HashMap::new(),
240240
user_defined_types: HashMap::new(),
241-
},
241+
}),
242242
)]
243243
.iter()
244244
.cloned()
@@ -251,7 +251,7 @@ mod tests {
251251
metadata
252252
.keyspaces
253253
.values()
254-
.map(|keyspace| &keyspace.strategy),
254+
.map(|keyspace| &keyspace.as_ref().unwrap().strategy),
255255
);
256256

257257
let check = |token, replication_factor, expected_node_ids| {
@@ -293,7 +293,7 @@ mod tests {
293293
metadata
294294
.keyspaces
295295
.values()
296-
.map(|keyspace| &keyspace.strategy),
296+
.map(|keyspace| &keyspace.as_ref().unwrap().strategy),
297297
);
298298

299299
let check = |token, dc, replication_factor, expected_node_ids| {

scylla/src/routing/locator/test.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,18 +118,18 @@ pub(crate) fn mock_metadata_for_token_aware_tests() -> Metadata {
118118
let keyspaces = [
119119
(
120120
KEYSPACE_SS_RF_2.into(),
121-
Keyspace {
121+
Ok(Keyspace {
122122
strategy: Strategy::SimpleStrategy {
123123
replication_factor: 2,
124124
},
125125
tables: HashMap::new(),
126126
views: HashMap::new(),
127127
user_defined_types: HashMap::new(),
128-
},
128+
}),
129129
),
130130
(
131131
KEYSPACE_NTS_RF_2.into(),
132-
Keyspace {
132+
Ok(Keyspace {
133133
strategy: Strategy::NetworkTopologyStrategy {
134134
datacenter_repfactors: [("eu".to_owned(), 2), ("us".to_owned(), 2)]
135135
.into_iter()
@@ -138,11 +138,11 @@ pub(crate) fn mock_metadata_for_token_aware_tests() -> Metadata {
138138
tables: HashMap::new(),
139139
views: HashMap::new(),
140140
user_defined_types: HashMap::new(),
141-
},
141+
}),
142142
),
143143
(
144144
KEYSPACE_NTS_RF_3.into(),
145-
Keyspace {
145+
Ok(Keyspace {
146146
strategy: Strategy::NetworkTopologyStrategy {
147147
datacenter_repfactors: [("eu".to_owned(), 3), ("us".to_owned(), 3)]
148148
.into_iter()
@@ -151,7 +151,7 @@ pub(crate) fn mock_metadata_for_token_aware_tests() -> Metadata {
151151
tables: HashMap::new(),
152152
views: HashMap::new(),
153153
user_defined_types: HashMap::new(),
154-
},
154+
}),
155155
),
156156
]
157157
.iter()
@@ -199,7 +199,10 @@ pub(crate) fn create_ring(metadata: &Metadata) -> impl Iterator<Item = (Token, A
199199

200200
pub(crate) fn create_locator(metadata: &Metadata) -> ReplicaLocator {
201201
let ring = create_ring(metadata);
202-
let strategies = metadata.keyspaces.values().map(|ks| &ks.strategy);
202+
let strategies = metadata
203+
.keyspaces
204+
.values()
205+
.map(|ks| &ks.as_ref().unwrap().strategy);
203206

204207
ReplicaLocator::new(ring, strategies, TabletsInfo::new())
205208
}

0 commit comments

Comments
 (0)