-
Notifications
You must be signed in to change notification settings - Fork 399
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove Progress.is_learner #119
Conversation
2810600
to
4dd2e63
Compare
d861453
to
f8f30f5
Compare
c468ee8
to
a744827
Compare
benches/suites/progress_set.rs
Outdated
b.iter(|| ProgressSet::new()); | ||
}; | ||
|
||
c.bench_function(&format!("ProgressSet::new"), bench); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about c.bench_function("ProgressSet::new", bench)
?
e250876
to
546b926
Compare
546b926
to
911a27a
Compare
src/raft.rs
Outdated
@@ -1993,12 +1993,13 @@ impl<T: Storage> Raft<T> { | |||
fn check_quorum_active(&mut self) -> bool { | |||
let self_id = self.id; | |||
let mut act = 0; | |||
let learners = self.prs().learner_ids().clone(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The clone here seems the best way, as much as I hate it. Since we use .mut_prs()
and iterate we have a mutable borrow out for self
.
We copy this HashSet<u64>
which should only have learner _ids() in it, which should be not unreasonably large. An alternative is we can clone voter_ids()
which should always be reasonable even if there are many learners. The downside being we always have the cost of the voters (3-7 usually).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use take_prs
to get around the lifetime check just as other places already did.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I always feel so dirty doing this. 🤣 But yes you're right.
src/raft.rs
Outdated
if let Some(progress) = self.prs().get(id) { | ||
// If progress.is_learner == learner, then it's already inserted as what it should be, return early to avoid error. | ||
if progress.is_learner == learner { | ||
if self.prs().get(id).is_some() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not necessary any more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. insert_learner
and similar functions do the check already. We can check the result to reflect errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. I will make this function (which is private) return a Result<()>
. I would like to make the callers return a Result<()>
in 0.5.0.
See #129.
rest LGTM. Nice work! |
@BusyJay Can you take another look? |
PTAL @BusyJay . |
@BusyJay Please take a look again, the test name is fixed. |
3e3d1b3
to
22e6d02
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rest LGTM
@siddontang Resolved, PTAL. I think it's ready for merge. |
121: Move poll & quorum functionality into ProgressSet r=Hoverbear a=Hoverbear Based off #119. **You are seeing that change set as well here, so go review that, then this after merging it! :)** Migrate poll and quorum related functionality inside `ProgressSet`. These functions operated on the `ProgressSet` anyways, they were just scoped to the `Raft`. # Rationale With the introduction of Joint Consensus, the idea of a Quorum is no longer always a single value. (If the cluster is in a joint state it actually has two quorums. The old configuration and the new one.) In the interest of isolating responsibility and dulling sharp edges, this PR migrates code the following functionality: * `check_quorum_active`: Migrated, it was doing a mutable fold on the peers and resetting their recent active, then returning if there was enough for quorum. The `ProgressSet` can do this itself, and it means we can avoid having to return some enum of either `(quorum)` or `(new_quorum, old_quorum)`. The `Raft` module need not care. * `poll`: Was split into a mutating vote-setter function, and a check function (non mutating). The check function returns a semantically meaningful enum now. This was a good idea since `poll(vote) >= quorum`, while still valid, may be comparing tuples or values. Internalizing this logic and instead returning a semantic value helps with understanding. * `minimum_committed_index`: Since in a joint consensus state we need to check the minimum committed index of both old and new, we can internalize this check and just return a bool. # Benefits This PR essentially amounts to API cleaning. It doesn't change any behavior, but it's a change we should do to make future work easier. # Future Work When Joint Consensus (#101 ) lands it will change these new functions to be joint-aware and correctly return values regardless of the configuration state. Co-authored-by: Hoverbear <andrew@hoverbear.org> Co-authored-by: Hoverbear <operator@hoverbear.org> Co-authored-by: A. Hobden <andrew@hoverbear.org> Co-authored-by: A. Hobden <operator@hoverbear.org> Co-authored-by: qupeng <onlyqupeng@gmail.com>
Remove the
is_learner
value fromProgress
.Rationale
In the process of Joint Consensus (#101) we will have two different
Configuration
sets during some points in operation.In #108 we made
Progress
a single set (instead of having separate sets for voters and learners).Progress
still held anis_learner
value, which meant we had two ways to determine if a node was a learner (via theProgressSet.has_learner()
andProgress.is_learner
). This is not necessary.We can use
ProgressSet.has_learner(id)
andProgressSet.has_voter(id)
exclusively.Benefits
Doing this helps minimize complexity, and reduces places we keep track of voter status.
Future Work
In the future we may be in a joint consensus state, meaning that the
Progress.is_learner
value could be incorrect (If you promoted a learner, then the old configuration still has it has a non-voter).This internalizes the concept of the
is_learner()
so we can minimize possible bug surface.