diff --git a/src/traft/failover.rs b/src/traft/failover.rs index 6bd719f3442a057af99de2d9474fc17353b841b4..0c48eb17f1719cef299311429a0538314abaa167 100644 --- a/src/traft/failover.rs +++ b/src/traft/failover.rs @@ -112,7 +112,7 @@ fn raft_update_peer( let mut req = req; let instance_id = &*req.instance_id; req.changes.retain(|ch| match ch { - super::PeerChange::Grade(grade) => { + super::PeerChange::CurrentGrade(grade) => { tlog!(Warning, "attempt to change grade by peer"; "instance_id" => instance_id, "grade" => grade.as_str(), diff --git a/src/traft/mod.rs b/src/traft/mod.rs index f9c7ae32107b90ca5438a86d4272505c26410043..8eae53246757ee8ad7f33df07ac6101e3c1cdbcf 100644 --- a/src/traft/mod.rs +++ b/src/traft/mod.rs @@ -441,7 +441,7 @@ pub struct Peer { pub commit_index: RaftIndex, /// The cluster's mind about actual state of this instance's activity. - pub grade: Grade, + pub current_grade: CurrentGrade, /// The desired state of this instance pub target_grade: TargetGrade, @@ -455,11 +455,11 @@ impl Encode for Peer {} impl Peer { pub fn is_active(&self) -> bool { - matches!(self.grade, Grade::Online) + matches!(self.current_grade, CurrentGrade::Online) } - pub fn has_grades(&self, current: Grade, target: TargetGrade) -> bool { - self.grade == current && self.target_grade == target + pub fn has_grades(&self, current: CurrentGrade, target: TargetGrade) -> bool { + self.current_grade == current && self.target_grade == target } } @@ -472,7 +472,7 @@ impl std::fmt::Display for Peer { self.raft_id, self.replicaset_id, self.peer_address, - self.grade, + self.current_grade, self.commit_index, &self.failure_domain, ) @@ -837,7 +837,7 @@ impl Encode for SyncRaftResponse {} /////////////////////////////////////////////////////////////////////////////// crate::define_str_enum! { /// Activity state of an instance. - pub enum Grade { + pub enum CurrentGrade { // Instance has gracefully shut down or has not been started yet. Offline = "Offline", // Instance has synced by commit index. @@ -856,7 +856,7 @@ crate::define_str_enum! { #[error("unknown grade {0:?}")] pub struct UnknownGrade(pub String); -impl Default for Grade { +impl Default for CurrentGrade { fn default() -> Self { Self::Offline } @@ -895,7 +895,7 @@ pub struct UpdatePeerRequest { #[derive(Clone, Debug, Serialize, Deserialize)] pub enum PeerChange { - Grade(Grade), + CurrentGrade(CurrentGrade), TargetGrade(TargetGrade), FailureDomain(FailureDomain), } @@ -911,8 +911,8 @@ impl UpdatePeerRequest { } } #[inline] - pub fn with_grade(mut self, grade: Grade) -> Self { - self.changes.push(PeerChange::Grade(grade)); + pub fn with_current_grade(mut self, current_grade: CurrentGrade) -> Self { + self.changes.push(PeerChange::CurrentGrade(current_grade)); self } #[inline] diff --git a/src/traft/node.rs b/src/traft/node.rs index b6e6c4420375a9021c9ab4093d73a3beb10ac2de..94b638d145354e8e7d2e7a0c9ebdace4e77aafb9 100644 --- a/src/traft/node.rs +++ b/src/traft/node.rs @@ -61,7 +61,7 @@ use crate::traft::{ use crate::traft::{PeerStorage, RaftSpaceAccess, Storage}; use super::OpResult; -use super::{Grade, TargetGrade}; +use super::{CurrentGrade, TargetGrade}; type RawNode = raft::RawNode<RaftSpaceAccess>; @@ -583,7 +583,7 @@ impl NodeImpl { if let Some(traft::Op::PersistPeer { peer }) = entry.op() { *topology_changed = true; - if peer.grade == Grade::Expelled && peer.raft_id == self.raft_id() { + if peer.current_grade == CurrentGrade::Expelled && peer.raft_id == self.raft_id() { // cannot exit during a transaction *expelled = true; } @@ -1025,12 +1025,13 @@ fn raft_conf_change_loop( // offline let to_offline = peers .iter() - .filter(|peer| peer.grade != Grade::Offline) + .filter(|peer| peer.current_grade != CurrentGrade::Offline) .find(|peer| peer.target_grade == TargetGrade::Offline); if let Some(peer) = to_offline { let instance_id = peer.instance_id.clone(); let cluster_id = storage.cluster_id().unwrap().unwrap(); - let req = UpdatePeerRequest::new(instance_id, cluster_id).with_grade(Grade::Offline); + let req = UpdatePeerRequest::new(instance_id, cluster_id) + .with_current_grade(CurrentGrade::Offline); let res = node.handle_topology_request_and_wait(req.into()); if let Err(e) = res { tlog!(Warning, "failed to set peer offline: {e}"; @@ -1044,7 +1045,7 @@ fn raft_conf_change_loop( // raft sync let to_sync = peers .iter() - .find(|peer| peer.has_grades(Grade::Offline, TargetGrade::Online)); + .find(|peer| peer.has_grades(CurrentGrade::Offline, TargetGrade::Online)); if let Some(peer) = to_sync { let commit = storage.commit().unwrap().unwrap(); @@ -1068,7 +1069,7 @@ fn raft_conf_change_loop( let cluster_id = storage.cluster_id().unwrap().unwrap(); let req = UpdatePeerRequest::new(peer.instance_id.clone(), cluster_id) - .with_grade(Grade::RaftSynced); + .with_current_grade(CurrentGrade::RaftSynced); global() .expect("can't be deinitialized") .handle_topology_request_and_wait(req.into()) @@ -1076,7 +1077,7 @@ fn raft_conf_change_loop( match res { Ok(peer) => { tlog!(Info, "raft sync processed"); - debug_assert!(peer.grade == Grade::RaftSynced); + debug_assert!(peer.current_grade == CurrentGrade::RaftSynced); } Err(e) => { tlog!(Warning, "raft sync failed: {e}"; @@ -1097,7 +1098,7 @@ fn raft_conf_change_loop( // replication let to_replicate = peers .iter() - .find(|peer| peer.has_grades(Grade::RaftSynced, TargetGrade::Online)); + .find(|peer| peer.has_grades(CurrentGrade::RaftSynced, TargetGrade::Online)); if let Some(peer) = to_replicate { let replicaset_id = &peer.replicaset_id; let replicaset_iids = unwrap_ok_or!( @@ -1159,7 +1160,7 @@ fn raft_conf_change_loop( let peer_iid_2 = peer_iid.clone(); let res = resp.and_then(move |replication::Response { lsn }| { let req = UpdatePeerRequest::new(peer_iid_2, cluster_id) - .with_grade(Grade::Replicated); + .with_current_grade(CurrentGrade::Replicated); node.handle_topology_request_and_wait(req.into()) .map(|_| lsn) }); @@ -1191,11 +1192,12 @@ fn raft_conf_change_loop( let to_online = peers .iter() - .find(|peer| peer.has_grades(Grade::Replicated, TargetGrade::Online)); + .find(|peer| peer.has_grades(CurrentGrade::Replicated, TargetGrade::Online)); if let Some(peer) = to_online { let instance_id = peer.instance_id.clone(); let cluster_id = node.storage.cluster_id().unwrap().unwrap(); - let req = UpdatePeerRequest::new(instance_id, cluster_id).with_grade(Grade::Online); + let req = UpdatePeerRequest::new(instance_id, cluster_id) + .with_current_grade(CurrentGrade::Online); let res = node.handle_topology_request_and_wait(req.into()); if let Err(e) = res { tlog!(Warning, "failed to set peer online: {e}"; @@ -1360,7 +1362,8 @@ fn expel_on_leader(req: ExpelRequest) -> Result<ExpelResponse, Box<dyn std::erro return Err(Box::from("not a leader")); } - let req2 = UpdatePeerRequest::new(req.instance_id, req.cluster_id).with_grade(Grade::Expelled); + let req2 = UpdatePeerRequest::new(req.instance_id, req.cluster_id) + .with_current_grade(CurrentGrade::Expelled); node.handle_topology_request_and_wait(req2.into())?; Ok(ExpelResponse {}) diff --git a/src/traft/storage.rs b/src/traft/storage.rs index 5338c18b415d9052ddf1a9f6017f54275130b697..f0f02a25432c184342a02adba3558bb278f4e6da 100644 --- a/src/traft/storage.rs +++ b/src/traft/storage.rs @@ -453,7 +453,7 @@ define_peer_fields! { ReplicasetId : String = ("replicaset_id", FieldType::String) ReplicasetUuid : String = ("replicaset_uuid", FieldType::String) CommitIndex : RaftIndex = ("commit_index", FieldType::Unsigned) - Grade : traft::Grade = ("grade", FieldType::String) + CurrentGrade : traft::CurrentGrade = ("current_grade", FieldType::String) TargetGrade : traft::TargetGrade = ("target_grade", FieldType::String) FailureDomain : traft::FailureDomain = ("failure_domain", FieldType::Map) } @@ -556,7 +556,7 @@ macro_rules! assert_err { inventory::submit!(crate::InnerTest { name: "test_storage_peers", body: || { - use traft::{Grade, TargetGrade}; + use traft::{CurrentGrade, TargetGrade}; let mut raft_group = Storage::space(RAFT_GROUP).unwrap(); @@ -564,13 +564,13 @@ inventory::submit!(crate::InnerTest { for peer in vec![ // r1 - ("i1", "i1-uuid", 1u64, "addr:1", "r1", "r1-uuid", 1u64, Grade::Online, TargetGrade::Online, &faildom,), - ("i2", "i2-uuid", 2u64, "addr:2", "r1", "r1-uuid", 2, Grade::Online, TargetGrade::Online, &faildom,), + ("i1", "i1-uuid", 1u64, "addr:1", "r1", "r1-uuid", 1u64, CurrentGrade::Online, TargetGrade::Online, &faildom,), + ("i2", "i2-uuid", 2u64, "addr:2", "r1", "r1-uuid", 2, CurrentGrade::Online, TargetGrade::Online, &faildom,), // r2 - ("i3", "i3-uuid", 3u64, "addr:3", "r2", "r2-uuid", 10, Grade::Online, TargetGrade::Online, &faildom,), - ("i4", "i4-uuid", 4u64, "addr:4", "r2", "r2-uuid", 10, Grade::Online, TargetGrade::Online, &faildom,), + ("i3", "i3-uuid", 3u64, "addr:3", "r2", "r2-uuid", 10, CurrentGrade::Online, TargetGrade::Online, &faildom,), + ("i4", "i4-uuid", 4u64, "addr:4", "r2", "r2-uuid", 10, CurrentGrade::Online, TargetGrade::Online, &faildom,), // r3 - ("i5", "i5-uuid", 5u64, "addr:5", "r3", "r3-uuid", 10, Grade::Online, TargetGrade::Online, &faildom,), + ("i5", "i5-uuid", 5u64, "addr:5", "r3", "r3-uuid", 10, CurrentGrade::Online, TargetGrade::Online, &faildom,), ] { raft_group.put(&peer).unwrap(); } @@ -599,8 +599,8 @@ inventory::submit!(crate::InnerTest { " and new tuple", r#" - ["i99", "", 1, "", "", "", 0, "{goff}", "{tgon}", {{}}]"#, ), - gon = Grade::Online, - goff = Grade::Offline, + gon = CurrentGrade::Online, + goff = CurrentGrade::Offline, tgon = TargetGrade::Online, ) ); diff --git a/src/traft/topology.rs b/src/traft/topology.rs index eb33d1b7c840947e46688300f00a1ae749c0111b..dc53cbec925a796d855cfff30c9207dd1d87be4e 100644 --- a/src/traft/topology.rs +++ b/src/traft/topology.rs @@ -4,7 +4,7 @@ use crate::traft::instance_uuid; use crate::traft::replicaset_uuid; use crate::traft::FailureDomain; use crate::traft::Peer; -use crate::traft::{Grade, TargetGrade}; +use crate::traft::{CurrentGrade, TargetGrade}; use crate::traft::{InstanceId, RaftId, ReplicasetId}; use crate::traft::{PeerChange, UpdatePeerRequest}; use crate::util::Uppercase; @@ -166,7 +166,7 @@ impl Topology { // Mark instance already active when it joins. // It prevents a disruption in case of the // instance_id collision. - grade: Grade::Offline, + current_grade: CurrentGrade::Offline, target_grade: TargetGrade::Offline, failure_domain, }; @@ -200,9 +200,9 @@ impl Topology { for change in req.changes { match change { - PeerChange::Grade(grade) => { - if peer.grade != Grade::Expelled { - peer.grade = grade; + PeerChange::CurrentGrade(grade) => { + if peer.current_grade != CurrentGrade::Expelled { + peer.current_grade = grade; } } PeerChange::TargetGrade(target_grade) => { @@ -249,7 +249,7 @@ mod tests { use crate::traft::FailureDomain; use crate::traft::Peer; use crate::traft::UpdatePeerRequest; - use crate::traft::{Grade, TargetGrade}; + use crate::traft::{CurrentGrade, TargetGrade}; use pretty_assertions::assert_eq; macro_rules! peers { @@ -288,7 +288,7 @@ mod tests { instance_uuid: instance_uuid($instance_id), replicaset_uuid: replicaset_uuid($replicaset_id), commit_index: raft::INVALID_INDEX, - grade: $grade, + current_grade: $grade, target_grade: $target_grade, failure_domain: { let _f = FailureDomain::default(); @@ -328,7 +328,7 @@ mod tests { $grade:expr $(,)? ) => { $topology.update_peer( - UpdatePeerRequest::new($instance_id.into(), "".into()).with_grade($grade), + UpdatePeerRequest::new($instance_id.into(), "".into()).with_current_grade($grade), ) }; } @@ -341,7 +341,7 @@ mod tests { ) => { $topology.update_peer( UpdatePeerRequest::new($instance_id.into(), "".into()) - .with_grade(Grade::Online) + .with_current_grade(CurrentGrade::Online) .with_failure_domain($failure_domain), ) }; @@ -360,39 +360,39 @@ mod tests { assert_eq!( join!(topology, None, None, "addr:1").unwrap(), - peer!(1, "i1", "r1", "addr:1", Grade::Offline, TargetGrade::Offline) + peer!(1, "i1", "r1", "addr:1", CurrentGrade::Offline, TargetGrade::Offline) ); assert_eq!( join!(topology, None, None, "addr:1").unwrap(), - peer!(2, "i2", "r2", "addr:1", Grade::Offline, TargetGrade::Offline) + peer!(2, "i2", "r2", "addr:1", CurrentGrade::Offline, TargetGrade::Offline) ); assert_eq!( join!(topology, None, Some("R3"), "addr:1").unwrap(), - peer!(3, "i3", "R3", "addr:1", Grade::Offline, TargetGrade::Offline) + peer!(3, "i3", "R3", "addr:1", CurrentGrade::Offline, TargetGrade::Offline) ); assert_eq!( join!(topology, Some("I4"), None, "addr:1").unwrap(), - peer!(4, "I4", "r3", "addr:1", Grade::Offline, TargetGrade::Offline) + peer!(4, "I4", "r3", "addr:1", CurrentGrade::Offline, TargetGrade::Offline) ); let mut topology = Topology::from_peers( - peers![(1, "i1", "r1", "addr:1", Grade::Offline, TargetGrade::Offline)] + peers![(1, "i1", "r1", "addr:1", CurrentGrade::Offline, TargetGrade::Offline)] ).with_replication_factor(1); assert_eq!( join!(topology, None, None, "addr:1").unwrap(), - peer!(2, "i2", "r2", "addr:1", Grade::Offline, TargetGrade::Offline) + peer!(2, "i2", "r2", "addr:1", CurrentGrade::Offline, TargetGrade::Offline) ); } #[test] fn test_override() { let mut topology = Topology::from_peers(peers![ - (1, "i1", "r1", "active:1", Grade::Online, TargetGrade::Online), - (2, "i2", "r2-original", "inactive:1", Grade::Offline, TargetGrade::Offline), + (1, "i1", "r1", "active:1", CurrentGrade::Online, TargetGrade::Online), + (2, "i2", "r2-original", "inactive:1", CurrentGrade::Offline, TargetGrade::Offline), ]) .with_replication_factor(2); @@ -420,7 +420,7 @@ mod tests { // Disruption isn't destructive if auto-expel allows (TODO). assert_eq!( join!(topology, Some("i2"), None, "inactive:2").unwrap(), - peer!(3, "i2", "r1", "inactive:2", Grade::Offline, TargetGrade::Offline), + peer!(3, "i2", "r1", "inactive:2", CurrentGrade::Offline, TargetGrade::Offline), // Attention: generated replicaset_id differs from the // original one, as well as raft_id. // That's a desired behavior. @@ -442,71 +442,71 @@ mod tests { #[test] fn test_instance_id_collision() { let mut topology = Topology::from_peers(peers![ - (1, "i1", "r1", "addr:1", Grade::Online, TargetGrade::Online), - (2, "i3", "r3", "addr:3", Grade::Online, TargetGrade::Online), + (1, "i1", "r1", "addr:1", CurrentGrade::Online, TargetGrade::Online), + (2, "i3", "r3", "addr:3", CurrentGrade::Online, TargetGrade::Online), // Attention: i3 has raft_id=2 ]); assert_eq!( join!(topology, None, Some("r2"), "addr:2").unwrap(), - peer!(3, "i3-2", "r2", "addr:2", Grade::Offline, TargetGrade::Offline), + peer!(3, "i3-2", "r2", "addr:2", CurrentGrade::Offline, TargetGrade::Offline), ); } #[test] fn test_replication_factor() { let mut topology = Topology::from_peers(peers![ - (9, "i9", "r9", "nowhere", Grade::Online, TargetGrade::Online), - (10, "i10", "r9", "nowhere", Grade::Online, TargetGrade::Online), + (9, "i9", "r9", "nowhere", CurrentGrade::Online, TargetGrade::Online), + (10, "i10", "r9", "nowhere", CurrentGrade::Online, TargetGrade::Online), ]) .with_replication_factor(2); assert_eq!( join!(topology, Some("i1"), None, "addr:1").unwrap(), - peer!(11, "i1", "r1", "addr:1", Grade::Offline, TargetGrade::Offline), + peer!(11, "i1", "r1", "addr:1", CurrentGrade::Offline, TargetGrade::Offline), ); assert_eq!( join!(topology, Some("i2"), None, "addr:2").unwrap(), - peer!(12, "i2", "r1", "addr:2", Grade::Offline, TargetGrade::Offline), + peer!(12, "i2", "r1", "addr:2", CurrentGrade::Offline, TargetGrade::Offline), ); assert_eq!( join!(topology, Some("i3"), None, "addr:3").unwrap(), - peer!(13, "i3", "r2", "addr:3", Grade::Offline, TargetGrade::Offline), + peer!(13, "i3", "r2", "addr:3", CurrentGrade::Offline, TargetGrade::Offline), ); assert_eq!( join!(topology, Some("i4"), None, "addr:4").unwrap(), - peer!(14, "i4", "r2", "addr:4", Grade::Offline, TargetGrade::Offline), + peer!(14, "i4", "r2", "addr:4", CurrentGrade::Offline, TargetGrade::Offline), ); } #[test] fn test_set_active() { let mut topology = Topology::from_peers(peers![ - (1, "i1", "r1", "nowhere", Grade::Online, TargetGrade::Online), - (2, "i2", "r2", "nowhere", Grade::Online, TargetGrade::Online), + (1, "i1", "r1", "nowhere", CurrentGrade::Online, TargetGrade::Online), + (2, "i2", "r2", "nowhere", CurrentGrade::Online, TargetGrade::Online), ]) .with_replication_factor(1); assert_eq!( - set_grade!(topology, "i1", Grade::Offline).unwrap(), - peer!(1, "i1", "r1", "nowhere", Grade::Offline, TargetGrade::Online), + set_grade!(topology, "i1", CurrentGrade::Offline).unwrap(), + peer!(1, "i1", "r1", "nowhere", CurrentGrade::Offline, TargetGrade::Online), ); // idempotency assert_eq!( - set_grade!(topology, "i1", Grade::Offline).unwrap(), - peer!(1, "i1", "r1", "nowhere", Grade::Offline, TargetGrade::Online), + set_grade!(topology, "i1", CurrentGrade::Offline).unwrap(), + peer!(1, "i1", "r1", "nowhere", CurrentGrade::Offline, TargetGrade::Online), ); assert_eq!( - set_grade!(topology, "i2", Grade::Offline).unwrap(), - peer!(2, "i2", "r2", "nowhere", Grade::Offline, TargetGrade::Online), + set_grade!(topology, "i2", CurrentGrade::Offline).unwrap(), + peer!(2, "i2", "r2", "nowhere", CurrentGrade::Offline, TargetGrade::Online), ); // idempotency assert_eq!( - set_grade!(topology, "i2", Grade::Offline).unwrap(), - peer!(2, "i2", "r2", "nowhere", Grade::Offline, TargetGrade::Online), + set_grade!(topology, "i2", CurrentGrade::Offline).unwrap(), + peer!(2, "i2", "r2", "nowhere", CurrentGrade::Offline, TargetGrade::Online), ); } @@ -641,7 +641,7 @@ mod tests { assert_eq!(peer.replicaset_id, "r1"); assert_eq!( - set_grade!(t, "i3", Grade::Offline).unwrap().failure_domain, + set_grade!(t, "i3", CurrentGrade::Offline).unwrap().failure_domain, faildoms! {planet: B, owner: V, dimension: C137}, ); diff --git a/test/int/test_couple.py b/test/int/test_couple.py index 147ccf64396f7c5e37d1eb77e71cba0546482064..6106fa86fb6d850ad3b55291f2c1e653de9e5558 100644 --- a/test/int/test_couple.py +++ b/test/int/test_couple.py @@ -113,8 +113,8 @@ def test_deactivation(cluster2: Cluster): instance.eval( """ raft_id = ... - grade = box.space.raft_group.index.raft_id:get(raft_id).grade - is_online = grade == 'Online' + current_grade = box.space.raft_group.index.raft_id:get(raft_id).current_grade + is_online = current_grade == 'Online' voters = box.space.raft_state:get('voters').value for _, voter in pairs(voters) do if voter == raft_id then @@ -173,12 +173,12 @@ def test_deactivation(cluster2: Cluster): def raft_update_peer( host: Instance, target: Instance, is_online: bool ) -> list[bool]: - grade = "Online" if is_online else "Offline" + current_grade = "Online" if is_online else "Offline" return host.call( ".raft_update_peer", target.instance_id, target.cluster_id, - [{"Grade": grade}, {"TargetGrade": "Online"}], + [{"CurrentGrade": current_grade}, {"TargetGrade": "Online"}], ) # check idempotency diff --git a/test/int/test_expelling.py b/test/int/test_expelling.py index c554d125329175986dc4429b2b89a0e053832f27..946fb711950c3fcda319673c6f187c69a69ca8db 100644 --- a/test/int/test_expelling.py +++ b/test/int/test_expelling.py @@ -9,11 +9,11 @@ def cluster3(cluster: Cluster): def assert_peer_expelled(expelled_peer: Instance, instance: Instance): - grade = instance.eval( - "return box.space.raft_group.index.instance_id:get(...).grade", + current_grade = instance.eval( + "return box.space.raft_group.index.instance_id:get(...).current_grade", expelled_peer.instance_id, ) - assert grade == "Expelled" + assert current_grade == "Expelled" def assert_voters(voters: list[Instance], instance: Instance):