From 6182058bb07bdea892fbe7ffe5a35b140470f1dd Mon Sep 17 00:00:00 2001 From: Muhamad Awad Date: Thu, 6 Feb 2025 15:05:17 +0100 Subject: [PATCH] Fix configuration compatibility issues Summary: Making sure a single node server v1.2 can still work with a v1.1.6 config --- crates/local-cluster-runner/Cargo.toml | 2 +- crates/local-cluster-runner/src/node/mod.rs | 6 ++++-- crates/metadata-server/src/lib.rs | 2 +- crates/metadata-server/src/raft/server.rs | 3 ++- crates/types/src/config/common.rs | 11 +++++++++-- crates/types/src/config/metadata_server.rs | 14 ++++++++++++-- server/tests/raft_metadata_cluster.rs | 12 +++++++----- 7 files changed, 36 insertions(+), 14 deletions(-) diff --git a/crates/local-cluster-runner/Cargo.toml b/crates/local-cluster-runner/Cargo.toml index 542bd489be..17d2bc7585 100644 --- a/crates/local-cluster-runner/Cargo.toml +++ b/crates/local-cluster-runner/Cargo.toml @@ -16,7 +16,7 @@ workspace-hack = { version = "0.1", path = "../../workspace-hack" } restate-core = { workspace = true } restate-metadata-server = { workspace = true } # nb features here will also affect the compiled restate-server binary in integration tests -restate-types = { workspace = true, features = ["unsafe-mutable-config"] } +restate-types = { workspace = true, features = ["unsafe-mutable-config", "test-util"] } anyhow = { workspace = true } arc-swap = { workspace = true } diff --git a/crates/local-cluster-runner/src/node/mod.rs b/crates/local-cluster-runner/src/node/mod.rs index 558caa711b..a0f20cfceb 100644 --- a/crates/local-cluster-runner/src/node/mod.rs +++ b/crates/local-cluster-runner/src/node/mod.rs @@ -180,11 +180,13 @@ impl Node { base_config.common.auto_provision = false; base_config.common.log_disable_ansi_codes = true; if !matches!( - base_config.metadata_server.kind, + base_config.metadata_server.kind(), MetadataServerKind::Raft(_) ) { info!("Setting the metadata server to embedded"); - base_config.metadata_server.kind = MetadataServerKind::Raft(RaftOptions::default()); + base_config + .metadata_server + .set_kind(MetadataServerKind::Raft(RaftOptions::default())); } for node_id in 1..=size { diff --git a/crates/metadata-server/src/lib.rs b/crates/metadata-server/src/lib.rs index 3f14c7aa90..c763f2e8f7 100644 --- a/crates/metadata-server/src/lib.rs +++ b/crates/metadata-server/src/lib.rs @@ -188,7 +188,7 @@ pub async fn create_metadata_server( server_builder: &mut NetworkServerBuilder, ) -> anyhow::Result { metric_definitions::describe_metrics(); - match metadata_server_options.kind { + match metadata_server_options.kind() { MetadataServerKind::Local => LocalMetadataServer::create( metadata_server_options, rocksdb_options, diff --git a/crates/metadata-server/src/raft/server.rs b/crates/metadata-server/src/raft/server.rs index 89122c4706..769b48b4ce 100644 --- a/crates/metadata-server/src/raft/server.rs +++ b/crates/metadata-server/src/raft/server.rs @@ -540,7 +540,8 @@ impl Member { connection_manager.store(Some(Arc::new(new_connection_manager))); let_assert!( - MetadataServerKind::Raft(raft_options) = &Configuration::pinned().metadata_server.kind, + MetadataServerKind::Raft(raft_options) = + &Configuration::pinned().metadata_server.kind(), "Expecting that the replicated/raft metadata server has been configured" ); diff --git a/crates/types/src/config/common.rs b/crates/types/src/config/common.rs index 381bc28c98..935e89d391 100644 --- a/crates/types/src/config/common.rs +++ b/crates/types/src/config/common.rs @@ -628,6 +628,7 @@ enum MetadataClientKindShadow { #[serde(alias = "embedded")] Native { address: Option, + #[serde(default)] addresses: Vec, }, Etcd { @@ -657,8 +658,14 @@ impl TryFrom for MetadataClientKind { Self::Native { addresses: match address { - Some(address) if addresses == vec![default_address] => vec![address], - Some(_) => return Err("Conflicting configuration, embedded metadata-store-client cannot have both `address` and `addresses`"), + Some(address) + if addresses.is_empty() || addresses == vec![default_address] => + { + vec![address] + } + Some(_) => { + return Err("Conflicting configuration, embedded metadata-client cannot have both `address` and `addresses`"); + } None => addresses, }, } diff --git a/crates/types/src/config/metadata_server.rs b/crates/types/src/config/metadata_server.rs index e614f62c1a..b079df2dbb 100644 --- a/crates/types/src/config/metadata_server.rs +++ b/crates/types/src/config/metadata_server.rs @@ -58,8 +58,9 @@ pub struct MetadataServerOptions { /// Type of metadata server to start /// /// The type of metadata server to start when running the metadata store role. + // defined as Option<_> for backward compatibility with version < v1.2 #[serde(flatten)] - pub kind: MetadataServerKind, + kind: Option, } #[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)] @@ -78,6 +79,15 @@ pub enum MetadataServerKind { } impl MetadataServerOptions { + pub fn kind(&self) -> MetadataServerKind { + self.kind.clone().unwrap_or_default() + } + + #[cfg(any(test, feature = "test-util"))] + pub fn set_kind(&mut self, kind: MetadataServerKind) { + self.kind = Some(kind); + } + pub fn apply_common(&mut self, common: &CommonOptions) { self.rocksdb.apply_common(&common.rocksdb); @@ -126,7 +136,7 @@ impl Default for MetadataServerOptions { rocksdb_memory_budget: None, rocksdb_memory_ratio: 0.01, rocksdb, - kind: MetadataServerKind::default(), + kind: Some(MetadataServerKind::default()), } } } diff --git a/server/tests/raft_metadata_cluster.rs b/server/tests/raft_metadata_cluster.rs index 30afb71e7e..b2c1525cb5 100644 --- a/server/tests/raft_metadata_cluster.rs +++ b/server/tests/raft_metadata_cluster.rs @@ -119,11 +119,13 @@ async fn raft_metadata_cluster_chaos_test() -> googletest::Result<()> { let num_nodes = 3; let chaos_duration = Duration::from_secs(20); let mut base_config = Configuration::default(); - base_config.metadata_server.kind = MetadataServerKind::Raft(RaftOptions { - raft_election_tick: NonZeroUsize::new(5).expect("5 to be non zero"), - raft_heartbeat_tick: NonZeroUsize::new(2).expect("2 to be non zero"), - ..RaftOptions::default() - }); + base_config + .metadata_server + .set_kind(MetadataServerKind::Raft(RaftOptions { + raft_election_tick: NonZeroUsize::new(5).expect("5 to be non zero"), + raft_heartbeat_tick: NonZeroUsize::new(2).expect("2 to be non zero"), + ..RaftOptions::default() + })); let nodes = Node::new_test_nodes( base_config,