Skip to content
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

fix a bug about initialized storage's term #214

Merged
merged 8 commits into from
Apr 12, 2019
Merged

Conversation

hicqu
Copy link
Contributor

@hicqu hicqu commented Apr 10, 2019

Try to resolve same problem with #213 , but with a different way.

This PR changes initialized storage's term from 0 to 1. So all place we need to call match_term won't get 0 as parameter, so the problem is resolved.

However more test cases need to be updated.
Please compare this PR with #213 , we only need to merge 1.

@Hoverbear
Copy link
Contributor

@hicqu Which solution do you think is most elegant and simple to understand?

@@ -61,21 +61,39 @@ pub struct Network {
}

impl Network {
/// Initializes a network from peers.
/// Get a base config. Calling `Network::new` will initialize peers with this config.
pub fn base_config() -> Config {
Copy link
Contributor

@Hoverbear Hoverbear Apr 10, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub fn base_config() -> Config {
pub fn default_config() -> Config {

@Hoverbear Hoverbear requested review from Hoverbear and BusyJay and removed request for Hoverbear April 10, 2019 18:07
src/raft.rs Outdated
@@ -2040,7 +2044,10 @@ impl<T: Storage> Raft<T> {

let next_idx = self.raft_log.last_index() + 1;
let mut prs = ProgressSet::restore_snapmeta(meta, next_idx, self.max_inflight);
prs.get_mut(self.id).unwrap().matched = next_idx - 1;
if let Some(pr) = prs.get_mut(self.id) {
// The snapshot could be too old so that it doesn't contain the peer.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? How can a leader send a snapshot to a node that it doesn't know?

/// Initialize a network from `peers` with explicitly specified `config`.
pub fn new_with_config(mut peers: Vec<Option<Interface>>, config: &Config) -> Network {
let peer_addrs: Vec<u64> = (1..=peers.len() as u64).collect();
for (i, id) in peer_addrs.iter().enumerate() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use zip?

let r = Raft::new(&config, store).unwrap().into();
npeers.insert(id, r);
}
Some(mut p) => {
p.initial(id, &peer_addrs);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why initial is unnecessary?

Copy link
Contributor Author

@hicqu hicqu Apr 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because all tests which need initial are fixed. I think initial is a not a good logic because it does additional changes to the peers, which should be already set correctly when the peer is created by Raft::new.

let n2 = new_test_raft_with_prevote(2, vec![], 10, 1, new_storage(), pre_vote);
let mut nt = Network::new(vec![Some(n1), Some(n2)]);
nt.send(vec![new_message(1, 1, MessageType::MsgHup, 0)]);
let messages = nt.read_messages();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there will be any messages.

(StateRole::Follower, 2, 3, INVALID_ID, false),
(StateRole::Follower, 3, 0, INVALID_ID, true),
(StateRole::Follower, 3, 1, INVALID_ID, true),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the difference between L1425 and L1426?

(StateRole::Leader, 3, 3, 1, true),
(StateRole::PreCandidate, 3, 3, 1, true),
(StateRole::Candidate, 3, 3, 1, true),
(StateRole::Follower, 4, 1, INVALID_ID, true),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

L1429 and L1430 seem the same.

@hicqu
Copy link
Contributor Author

hicqu commented Apr 11, 2019

@Hoverbear I think this PR is better because we won't meet term ==0 anymore. Messages with term 0 is treated as local messages.

@Hoverbear
Copy link
Contributor

@hicqu Ok, do you want to close the other then?

@hicqu hicqu merged commit 2ebbed5 into tikv:master Apr 12, 2019
@hicqu hicqu deleted the term-fix branch April 12, 2019 10:01
@Hoverbear Hoverbear added this to the 0.6.0 milestone Apr 12, 2019
BusyJay added a commit that referenced this pull request Mar 26, 2020
This PR removes the modifications of index during initialization, which will
allow raft's log index goes from 0 again. This is important as many existing
test cases rely on it, especially those related to flow control. Those cases
pass on master in an accidental way, checking what are exact broken will be
too much work. Besides upstream patches from etcd also rely on the same
assumption, only forbid growing from 0 in raft-rs will make it hard to port
patches.

Most of the changes are basically revert of index changes introduced from #196
and #214.

Signed-off-by: Jay Lee <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants