Skip to content

Commit 342d0de

Browse files
committed
Change: rename variants in ChangeMembers, add AddVoters
Rename `ChangeMembers::AddVoter` to `AddVoterIds`, because it just updates voter ids. Rename `ChangeMembers::RemoveVoter` to `RemoveVoters`. Add `ChangeMembers::AddVoters(BTreeMap)` to add voters with corresponding `Node`, i.e., it adds nodes as learners and update the voter-ids in a `Membership`.
1 parent e978781 commit 342d0de

File tree

4 files changed

+62
-19
lines changed

4 files changed

+62
-19
lines changed

openraft/src/change_members.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,34 @@ use crate::NodeId;
88
#[derive(PartialEq, Eq)]
99
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize), serde(bound = ""))]
1010
pub enum ChangeMembers<NID: NodeId, N: Node> {
11-
AddVoter(BTreeSet<NID>),
12-
RemoveVoter(BTreeSet<NID>),
11+
/// Upgrade learners to voters.
12+
///
13+
/// The learners have to present or [`error::LearnerNotFound`](`crate::error::LearnerNotFound`)
14+
/// error will be returned.
15+
AddVoterIds(BTreeSet<NID>),
16+
17+
/// Add voters with corresponding nodes.
18+
AddVoters(BTreeMap<NID, N>),
19+
20+
/// Remove voters, leave removed voters as learner or not.
21+
RemoveVoters(BTreeSet<NID>),
22+
23+
/// Replace voter ids with a new set. The node of every new voter has to already be a learner.
1324
ReplaceAllVoters(BTreeSet<NID>),
25+
26+
/// Add nodes to membership, as learners.
1427
AddNodes(BTreeMap<NID, N>),
28+
29+
/// Remove nodes from membership.
30+
///
31+
/// If a node is still a voter, it returns
32+
/// [`error::LearnerNotFound`](`crate::error::LearnerNotFound`) error.
1533
RemoveNodes(BTreeSet<NID>),
34+
35+
/// Replace all nodes with a new set.
36+
///
37+
/// Every voter has to have a corresponding node in the new
38+
/// set, otherwise it returns [`error::LearnerNotFound`](`crate::error::LearnerNotFound`) error.
1639
ReplaceAllNodes(BTreeMap<NID, N>),
1740
}
1841

openraft/src/membership/change_handler.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ mod tests {
9999
#[test]
100100
fn test_apply_not_committed() -> anyhow::Result<()> {
101101
let new = || MembershipState::new(effmem(2, 2, m1()), effmem(3, 4, m123_345()));
102-
let res = new().change_handler().apply(ChangeMembers::AddVoter(btreeset! {1}), false);
102+
let res = new().change_handler().apply(ChangeMembers::AddVoterIds(btreeset! {1}), false);
103103

104104
assert_eq!(
105105
Err(ChangeMembershipError::InProgress(InProgress {
@@ -115,7 +115,7 @@ mod tests {
115115
#[test]
116116
fn test_apply_empty_voters() -> anyhow::Result<()> {
117117
let new = || MembershipState::new(effmem(3, 4, m1()), effmem(3, 4, m1()));
118-
let res = new().change_handler().apply(ChangeMembers::RemoveVoter(btreeset! {1}), false);
118+
let res = new().change_handler().apply(ChangeMembers::RemoveVoters(btreeset! {1}), false);
119119

120120
assert_eq!(Err(ChangeMembershipError::EmptyMembership(EmptyMembership {})), res);
121121

@@ -125,7 +125,7 @@ mod tests {
125125
#[test]
126126
fn test_apply_learner_not_found() -> anyhow::Result<()> {
127127
let new = || MembershipState::new(effmem(3, 4, m1()), effmem(3, 4, m1()));
128-
let res = new().change_handler().apply(ChangeMembers::AddVoter(btreeset! {2}), false);
128+
let res = new().change_handler().apply(ChangeMembers::AddVoterIds(btreeset! {2}), false);
129129

130130
assert_eq!(
131131
Err(ChangeMembershipError::LearnerNotFound(LearnerNotFound { node_id: 2 })),
@@ -140,14 +140,14 @@ mod tests {
140140
let new = || MembershipState::new(effmem(3, 4, m12()), effmem(3, 4, m123_345()));
141141

142142
// Do not leave removed voters as learner
143-
let res = new().change_handler().apply(ChangeMembers::RemoveVoter(btreeset! {1,2}), false);
143+
let res = new().change_handler().apply(ChangeMembers::RemoveVoters(btreeset! {1,2}), false);
144144
assert_eq!(
145145
Ok(Membership::new(vec![btreeset! {3,4,5}], btreemap! {3=>(),4=>(),5=>()})),
146146
res
147147
);
148148

149149
// Leave removed voters as learner
150-
let res = new().change_handler().apply(ChangeMembers::RemoveVoter(btreeset! {1,2}), true);
150+
let res = new().change_handler().apply(ChangeMembers::RemoveVoters(btreeset! {1,2}), true);
151151
assert_eq!(
152152
Ok(Membership::new(
153153
vec![btreeset! {3,4,5}],

openraft/src/membership/membership.rs

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -402,14 +402,22 @@ where
402402
) -> Result<Self, ChangeMembershipError<NID>> {
403403
tracing::debug!(change = debug(&change), "{}", func_name!());
404404

405-
let last = self.get_joint_config().last().unwrap();
405+
let last = self.get_joint_config().last().unwrap().clone();
406406

407407
let new_membership = match change {
408-
ChangeMembers::AddVoter(add_voter_ids) => {
408+
ChangeMembers::AddVoterIds(add_voter_ids) => {
409409
let new_voter_ids = last.union(&add_voter_ids).copied().collect::<BTreeSet<_>>();
410410
self.next_coherent(new_voter_ids, retain)
411411
}
412-
ChangeMembers::RemoveVoter(remove_voter_ids) => {
412+
ChangeMembers::AddVoters(add_voters) => {
413+
// Add nodes without overriding existent
414+
self.nodes = Self::extend_nodes(self.nodes, &add_voters);
415+
416+
let add_voter_ids = add_voters.keys().copied().collect::<BTreeSet<_>>();
417+
let new_voter_ids = last.union(&add_voter_ids).copied().collect::<BTreeSet<_>>();
418+
self.next_coherent(new_voter_ids, retain)
419+
}
420+
ChangeMembers::RemoveVoters(remove_voter_ids) => {
413421
let new_voter_ids = last.difference(&remove_voter_ids).copied().collect::<BTreeSet<_>>();
414422
self.next_coherent(new_voter_ids, retain)
415423
}
@@ -480,7 +488,7 @@ mod tests {
480488

481489
// Add: no such learner
482490
{
483-
let res = m().change(ChangeMembers::AddVoter(btreeset! {4}), true);
491+
let res = m().change(ChangeMembers::AddVoterIds(btreeset! {4}), true);
484492
assert_eq!(
485493
Err(ChangeMembershipError::LearnerNotFound(LearnerNotFound { node_id: 4 })),
486494
res
@@ -489,7 +497,7 @@ mod tests {
489497

490498
// Add: ok
491499
{
492-
let res = m().change(ChangeMembers::AddVoter(btreeset! {3}), true);
500+
let res = m().change(ChangeMembers::AddVoterIds(btreeset! {3}), true);
493501
assert_eq!(
494502
Ok(Membership::<u64, ()> {
495503
configs: vec![btreeset! {1,2}, btreeset! {1,2,3}],
@@ -499,9 +507,21 @@ mod tests {
499507
);
500508
}
501509

510+
// AddVoters
511+
{
512+
let res = m().change(ChangeMembers::AddVoters(btreemap! {5=>()}), true);
513+
assert_eq!(
514+
Ok(Membership::<u64, ()> {
515+
configs: vec![btreeset! {1,2}, btreeset! {1,2,5}],
516+
nodes: btreemap! {1=>(),2=>(),3=>(),5=>()}
517+
}),
518+
res
519+
);
520+
}
521+
502522
// Remove: no such voter
503523
{
504-
let res = m().change(ChangeMembers::RemoveVoter(btreeset! {5}), true);
524+
let res = m().change(ChangeMembers::RemoveVoters(btreeset! {5}), true);
505525
assert_eq!(
506526
Ok(Membership::<u64, ()> {
507527
configs: vec![btreeset! {1,2}],
@@ -513,13 +533,13 @@ mod tests {
513533

514534
// Remove: become empty
515535
{
516-
let res = m().change(ChangeMembers::RemoveVoter(btreeset! {1,2}), true);
536+
let res = m().change(ChangeMembers::RemoveVoters(btreeset! {1,2}), true);
517537
assert_eq!(Err(ChangeMembershipError::EmptyMembership(EmptyMembership {})), res);
518538
}
519539

520540
// Remove: OK retain
521541
{
522-
let res = m().change(ChangeMembers::RemoveVoter(btreeset! {1}), true);
542+
let res = m().change(ChangeMembers::RemoveVoters(btreeset! {1}), true);
523543
assert_eq!(
524544
Ok(Membership::<u64, ()> {
525545
configs: vec![btreeset! {1,2}, btreeset! {2}],
@@ -531,7 +551,7 @@ mod tests {
531551

532552
// Remove: OK, not retain; learner not removed
533553
{
534-
let res = m().change(ChangeMembers::RemoveVoter(btreeset! {1}), false);
554+
let res = m().change(ChangeMembers::RemoveVoters(btreeset! {1}), false);
535555
assert_eq!(
536556
Ok(Membership::<u64, ()> {
537557
configs: vec![btreeset! {1,2}, btreeset! {2}],
@@ -547,7 +567,7 @@ mod tests {
547567
configs: vec![btreeset! {1,2}, btreeset! {2}],
548568
nodes: btreemap! {1=>(),2=>(),3=>()},
549569
};
550-
let res = mem.change(ChangeMembers::RemoveVoter(btreeset! {1}), false);
570+
let res = mem.change(ChangeMembers::RemoveVoters(btreeset! {1}), false);
551571
assert_eq!(
552572
Ok(Membership::<u64, ()> {
553573
configs: vec![btreeset! {2}],

openraft/tests/membership/t16_change_membership_cases.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ async fn change_from_to(old: BTreeSet<MemNodeId>, change_members: BTreeSet<MemNo
244244
/// Test change-membership by adding voters.
245245
#[tracing::instrument(level = "debug")]
246246
async fn change_by_add(old: BTreeSet<MemNodeId>, add: &[MemNodeId]) -> anyhow::Result<()> {
247-
let change = ChangeMembers::AddVoter(add.iter().copied().collect());
247+
let change = ChangeMembers::AddVoterIds(add.iter().copied().collect());
248248

249249
let mes = format!("from {:?} {:?}", old, change);
250250

@@ -312,7 +312,7 @@ async fn change_by_add(old: BTreeSet<MemNodeId>, add: &[MemNodeId]) -> anyhow::R
312312

313313
#[tracing::instrument(level = "debug")]
314314
async fn change_by_remove(old: BTreeSet<MemNodeId>, remove: &[MemNodeId]) -> anyhow::Result<()> {
315-
let change = ChangeMembers::RemoveVoter(remove.iter().copied().collect());
315+
let change = ChangeMembers::RemoveVoters(remove.iter().copied().collect());
316316

317317
let mes = format!("from {:?} {:?}", old, change);
318318

0 commit comments

Comments
 (0)