diff --git a/src/traft/topology.rs b/src/traft/topology.rs index 7ac89f57c820fb326c69fe00ad1f5f1bcd34a720..eb33d1b7c840947e46688300f00a1ae749c0111b 100644 --- a/src/traft/topology.rs +++ b/src/traft/topology.rs @@ -3,16 +3,14 @@ use std::collections::{BTreeMap, HashMap, HashSet}; use crate::traft::instance_uuid; use crate::traft::replicaset_uuid; use crate::traft::FailureDomain; -use crate::traft::Grade; use crate::traft::Peer; +use crate::traft::{Grade, TargetGrade}; use crate::traft::{InstanceId, RaftId, ReplicasetId}; use crate::traft::{PeerChange, UpdatePeerRequest}; use crate::util::Uppercase; use raft::INVALID_INDEX; -use super::TargetGrade; - pub struct Topology { replication_factor: u8, max_raft_id: RaftId, @@ -168,8 +166,8 @@ impl Topology { // Mark instance already active when it joins. // It prevents a disruption in case of the // instance_id collision. - grade: Grade::Online, - target_grade: super::TargetGrade::Online, + grade: Grade::Offline, + target_grade: TargetGrade::Offline, failure_domain, }; @@ -241,6 +239,7 @@ pub fn initial_peer( peer } +#[rustfmt::skip] #[cfg(test)] mod tests { use super::Topology; @@ -259,12 +258,13 @@ mod tests { $instance_id:literal, $replicaset_id:literal, $peer_address:literal, - $grade:expr + $grade:expr, + $target_grade:expr $(, $failure_domain:expr)? $(,)? ) ),* $(,)? ] => { vec![$( - peer!($raft_id, $instance_id, $replicaset_id, $peer_address, $grade $(,$failure_domain)?) + peer!($raft_id, $instance_id, $replicaset_id, $peer_address, $grade, $target_grade $(,$failure_domain)?) ),*] }; } @@ -275,7 +275,8 @@ mod tests { $instance_id:literal, $replicaset_id:literal, $peer_address:literal, - $grade:expr + $grade:expr, + $target_grade:expr $(, $failure_domain:expr)? $(,)? ) => { @@ -288,7 +289,7 @@ mod tests { replicaset_uuid: replicaset_uuid($replicaset_id), commit_index: raft::INVALID_INDEX, grade: $grade, - target_grade: TargetGrade::Online, + target_grade: $target_grade, failure_domain: { let _f = FailureDomain::default(); $( let _f = $failure_domain; )? @@ -359,38 +360,39 @@ mod tests { assert_eq!( join!(topology, None, None, "addr:1").unwrap(), - peer!(1, "i1", "r1", "addr:1", Grade::Online) + peer!(1, "i1", "r1", "addr:1", Grade::Offline, TargetGrade::Offline) ); assert_eq!( join!(topology, None, None, "addr:1").unwrap(), - peer!(2, "i2", "r2", "addr:1", Grade::Online) + peer!(2, "i2", "r2", "addr:1", Grade::Offline, TargetGrade::Offline) ); assert_eq!( join!(topology, None, Some("R3"), "addr:1").unwrap(), - peer!(3, "i3", "R3", "addr:1", Grade::Online) + peer!(3, "i3", "R3", "addr:1", Grade::Offline, TargetGrade::Offline) ); assert_eq!( join!(topology, Some("I4"), None, "addr:1").unwrap(), - peer!(4, "I4", "r3", "addr:1", Grade::Online) + peer!(4, "I4", "r3", "addr:1", Grade::Offline, TargetGrade::Offline) ); - let mut topology = Topology::from_peers(peers![(1, "i1", "r1", "addr:1", Grade::Online)]) - .with_replication_factor(1); + let mut topology = Topology::from_peers( + peers![(1, "i1", "r1", "addr:1", Grade::Offline, TargetGrade::Offline)] + ).with_replication_factor(1); assert_eq!( join!(topology, None, None, "addr:1").unwrap(), - peer!(2, "i2", "r2", "addr:1", Grade::Online) + peer!(2, "i2", "r2", "addr:1", Grade::Offline, TargetGrade::Offline) ); } #[test] fn test_override() { let mut topology = Topology::from_peers(peers![ - (1, "i1", "r1", "active:1", Grade::Online), - (2, "i2", "r2-original", "inactive:1", Grade::Offline), + (1, "i1", "r1", "active:1", Grade::Online, TargetGrade::Online), + (2, "i2", "r2-original", "inactive:1", Grade::Offline, TargetGrade::Offline), ]) .with_replication_factor(2); @@ -418,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::Online), + peer!(3, "i2", "r1", "inactive:2", Grade::Offline, TargetGrade::Offline), // Attention: generated replicaset_id differs from the // original one, as well as raft_id. // That's a desired behavior. @@ -440,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), - (2, "i3", "r3", "addr:3", Grade::Online), + (1, "i1", "r1", "addr:1", Grade::Online, TargetGrade::Online), + (2, "i3", "r3", "addr:3", Grade::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::Online), + peer!(3, "i3-2", "r2", "addr:2", Grade::Offline, TargetGrade::Offline), ); } #[test] fn test_replication_factor() { let mut topology = Topology::from_peers(peers![ - (9, "i9", "r9", "nowhere", Grade::Online), - (10, "i10", "r9", "nowhere", Grade::Online), + (9, "i9", "r9", "nowhere", Grade::Online, TargetGrade::Online), + (10, "i10", "r9", "nowhere", Grade::Online, TargetGrade::Online), ]) .with_replication_factor(2); assert_eq!( join!(topology, Some("i1"), None, "addr:1").unwrap(), - peer!(11, "i1", "r1", "addr:1", Grade::Online), + peer!(11, "i1", "r1", "addr:1", Grade::Offline, TargetGrade::Offline), ); assert_eq!( join!(topology, Some("i2"), None, "addr:2").unwrap(), - peer!(12, "i2", "r1", "addr:2", Grade::Online), + peer!(12, "i2", "r1", "addr:2", Grade::Offline, TargetGrade::Offline), ); assert_eq!( join!(topology, Some("i3"), None, "addr:3").unwrap(), - peer!(13, "i3", "r2", "addr:3", Grade::Online), + peer!(13, "i3", "r2", "addr:3", Grade::Offline, TargetGrade::Offline), ); assert_eq!( join!(topology, Some("i4"), None, "addr:4").unwrap(), - peer!(14, "i4", "r2", "addr:4", Grade::Online), + peer!(14, "i4", "r2", "addr:4", Grade::Offline, TargetGrade::Offline), ); } #[test] fn test_set_active() { let mut topology = Topology::from_peers(peers![ - (1, "i1", "r1", "nowhere", Grade::Online), - (2, "i2", "r2", "nowhere", Grade::Offline), + (1, "i1", "r1", "nowhere", Grade::Online, TargetGrade::Online), + (2, "i2", "r2", "nowhere", Grade::Online, TargetGrade::Online), ]) .with_replication_factor(1); assert_eq!( set_grade!(topology, "i1", Grade::Offline).unwrap(), - peer!(1, "i1", "r1", "nowhere", Grade::Offline), + peer!(1, "i1", "r1", "nowhere", Grade::Offline, TargetGrade::Online), ); // idempotency assert_eq!( set_grade!(topology, "i1", Grade::Offline).unwrap(), - peer!(1, "i1", "r1", "nowhere", Grade::Offline), + peer!(1, "i1", "r1", "nowhere", Grade::Offline, TargetGrade::Online), ); assert_eq!( - set_grade!(topology, "i2", Grade::Online).unwrap(), - peer!(2, "i2", "r2", "nowhere", Grade::Online), + set_grade!(topology, "i2", Grade::Offline).unwrap(), + peer!(2, "i2", "r2", "nowhere", Grade::Offline, TargetGrade::Online), ); // idempotency assert_eq!( - set_grade!(topology, "i2", Grade::Online).unwrap(), - peer!(2, "i2", "r2", "nowhere", Grade::Online), + set_grade!(topology, "i2", Grade::Offline).unwrap(), + peer!(2, "i2", "r2", "nowhere", Grade::Offline, TargetGrade::Online), ); }