drive members with addr
- Id
- b9fa82b7da828c17d386948350c5681a7e003bab
- Author
- Caio
- Commit time
- 2024-03-13T12:06:12+01:00
Modified src/member.rs
}
}
-impl<T: PartialEq + Clone> Members<T> {
+impl<T> Members<T>
+where
+ T: PartialEq + Clone + crate::Identity,
+{
pub(crate) fn num_active(&self) -> usize {
self.num_active
}
if let Some(known_member) = self
.inner
.iter_mut()
- .find(|member| &member.id == update.id())
+ .find(|member| member.id.addr() == update.id().addr())
{
if !condition(known_member) {
return Some(ApplySummary {
use alloc::vec;
use rand::{rngs::SmallRng, SeedableRng};
+ #[derive(Clone, Debug, PartialEq, Eq, Copy, PartialOrd, Ord)]
+ struct Id(&'static str);
+ impl crate::Identity for Id {
+ type Addr = &'static str;
+
+ fn renew(&self) -> Option<Self> {
+ None
+ }
+
+ fn addr(&self) -> Self::Addr {
+ self.0
+ }
+
+ fn has_same_prefix(&self, other: &Self) -> bool {
+ self.0 == other.0
+ }
+ }
+
use State::*;
#[test]
fn alive_transitions() {
- let mut member = Member::new("a", 0, Alive);
+ let mut member = Member::new(Id("a"), 0, Alive);
// Alive => Alive
assert!(
);
assert_eq!(Suspect, member.state);
- member = Member::new("b", 0, Alive);
+ member = Member::new(Id("b"), 0, Alive);
assert!(
member.change_state(member.incarnation + 1, Suspect),
"transition to suspect with higher incarnation"
#[test]
fn suspect_transitions() {
- let mut member = Member::new("a", 0, Suspect);
+ let mut member = Member::new(Id("a"), 0, Suspect);
// Suspect => Suspect
assert!(
#[test]
fn next_walks_sequentially_then_shuffles() {
- let ordered_ids = vec![1, 2, 3, 4, 5];
+ let ordered_ids = vec![Id("1"), Id("2"), Id("3"), Id("4"), Id("5")];
let mut members = Members::new(ordered_ids.iter().cloned().map(Member::alive).collect());
let mut rng = SmallRng::seed_from_u64(0xF0CA);
assert_eq!(
None,
- members.apply_existing_if(Member::alive(1), |_member| true),
+ members.apply_existing_if(Member::alive(Id("1")), |_member| true),
"Only yield None only if member is not found"
);
let mut rng = SmallRng::seed_from_u64(0xF0CA);
- let _ = members.apply(Member::alive(1), &mut rng);
+ let _ = members.apply(Member::alive(Id("1")), &mut rng);
assert_ne!(
None,
- members.apply_existing_if(Member::alive(1), |_member| true),
+ members.apply_existing_if(Member::alive(Id("1")), |_member| true),
"Must yield Some() if existing, regardless of condition"
);
assert_ne!(
None,
- members.apply_existing_if(Member::alive(1), |_member| false),
+ members.apply_existing_if(Member::alive(Id("1")), |_member| false),
"Must yield Some() if existing, regardless of condition"
);
}
let mut rng = SmallRng::seed_from_u64(0xF0CA);
// New and active member
- let res = members.apply(Member::suspect(1), &mut rng);
+ let res = members.apply(Member::suspect(Id("1")), &mut rng);
assert_eq!(
ApplySummary {
is_active_now: true,
// Failed attempt to change member id=1 to alive
// (since it's already suspect with same incarnation)
- let res = members.apply(Member::alive(1), &mut rng);
+ let res = members.apply(Member::alive(Id("1")), &mut rng);
assert_eq!(
ApplySummary {
is_active_now: true,
// Successful attempt at changing member id=1 to
// alive by using a higher incarnation
- let res = members.apply(Member::new(1, 1, State::Alive), &mut rng);
+ let res = members.apply(Member::new(Id("1"), 1, State::Alive), &mut rng);
assert_eq!(
ApplySummary {
is_active_now: true,
assert_eq!(1, members.len());
// Change existing member to down
- let res = members.apply(Member::down(1), &mut rng);
+ let res = members.apply(Member::down(Id("1")), &mut rng);
assert_eq!(
ApplySummary {
is_active_now: false,
assert_eq!(0, members.num_active());
// New and inactive member
- let res = members.apply(Member::down(2), &mut rng);
+ let res = members.apply(Member::down(Id("2")), &mut rng);
assert_eq!(
ApplySummary {
is_active_now: false,
assert_eq!(
None,
- members.remove_if_down(&1),
+ members.remove_if_down(&Id("1")),
"cant remove member that does not exist"
);
- let _ = members.apply(Member::alive(1), &mut rng);
+ let _ = members.apply(Member::alive(Id("1")), &mut rng);
assert_eq!(
None,
- members.remove_if_down(&1),
+ members.remove_if_down(&Id("1")),
"cant remove member that isnt down"
);
- let _ = members.apply(Member::down(1), &mut rng);
+ let _ = members.apply(Member::down(Id("1")), &mut rng);
assert_eq!(
- Some(Member::down(1)),
- members.remove_if_down(&1),
+ Some(Member::down(Id("1"))),
+ members.remove_if_down(&Id("1")),
"must return the removed member"
);
}
"next() should yield None when there are no members"
);
- let _ = members.apply(Member::down(-1), &mut rng);
- let _ = members.apply(Member::down(-2), &mut rng);
- let _ = members.apply(Member::down(-3), &mut rng);
+ let _ = members.apply(Member::down(Id("-1")), &mut rng);
+ let _ = members.apply(Member::down(Id("-2")), &mut rng);
+ let _ = members.apply(Member::down(Id("-3")), &mut rng);
assert_eq!(
None,
"next() should yield None when there are no active members"
);
- let _ = members.apply(Member::alive(1), &mut rng);
+ let _ = members.apply(Member::alive(Id("1")), &mut rng);
for _i in 0..10 {
assert_eq!(
- Some(1),
+ Some(Id("1")),
members.next(&mut rng).map(|m| m.id),
"next() should yield the same member if its the only active"
);
fn choose_active_members_behaviour() {
let members = Members::new(Vec::from([
// 5 active members
- Member::alive(1),
- Member::alive(2),
- Member::alive(3),
- Member::suspect(4),
- Member::suspect(5),
+ Member::alive(Id("1")),
+ Member::alive(Id("2")),
+ Member::alive(Id("3")),
+ Member::suspect(Id("4")),
+ Member::suspect(Id("5")),
// 2 down
- Member::down(6),
- Member::down(7),
+ Member::down(Id("6")),
+ Member::down(Id("7")),
]));
assert_eq!(7, members.len());
assert_eq!(2, out.len(), "Respects `wanted` even if we have more");
out.clear();
- members.choose_active_members(usize::MAX, &mut out, &mut rng, |&member_id| member_id > 4);
- assert_eq!(vec![Member::suspect(5)], out);
+ members.choose_active_members(usize::MAX, &mut out, &mut rng, |&member_id| {
+ member_id.0.parse::<usize>().expect("number") > 4
+ });
+ assert_eq!(vec![Member::suspect(Id("5"))], out);
}
}