-
Notifications
You must be signed in to change notification settings - Fork 1k
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
check if server is in configuration when receiving a voteRequest #526
Changes from 3 commits
db7ed9e
b8e8e45
2d614b5
826fce5
22e0e00
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2644,6 +2644,85 @@ func TestRaft_VoteNotGranted_WhenNodeNotInCluster(t *testing.T) { | |
} | ||
} | ||
|
||
func TestRaft_ClusterCanRegainStability_WhenNonVoterWithHigherTermJoin(t *testing.T) { | ||
// Make a cluster | ||
c := MakeCluster(3, t, nil) | ||
|
||
defer c.Close() | ||
|
||
// Get the leader | ||
leader := c.Leader() | ||
|
||
// Wait until we have 2 followers | ||
limit := time.Now().Add(c.longstopTimeout) | ||
var followers []*Raft | ||
for time.Now().Before(limit) && len(followers) != 2 { | ||
c.WaitEvent(nil, c.conf.CommitTimeout) | ||
followers = c.GetInState(Follower) | ||
} | ||
if len(followers) != 2 { | ||
t.Fatalf("expected two followers: %v", followers) | ||
} | ||
dhiaayachi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Remove a follower | ||
followerRemoved := followers[0] | ||
c.Disconnect(followerRemoved.localAddr) | ||
time.Sleep(c.propagateTimeout) | ||
|
||
future := leader.RemoveServer(followerRemoved.localID, 0, 0) | ||
if err := future.Error(); err != nil { | ||
t.Fatalf("err: %v", err) | ||
} | ||
|
||
//set that follower term to higher term to simulate a partitioning | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to simulate a partitioning? Isn't that what c.Disconnect is doing? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes disconnect would prohibit communication from the specified node to any node and from any node to that node. |
||
followerRemoved.setCurrentTerm(leader.getCurrentTerm() + 20) | ||
//Add the node back as NonVoter | ||
future = leader.AddNonvoter(followerRemoved.localID, followerRemoved.localAddr, 0, 0) | ||
if err := future.Error(); err != nil { | ||
t.Fatalf("err: %v", err) | ||
} | ||
|
||
c.FullyConnect() | ||
|
||
// Wait a while | ||
time.Sleep(c.propagateTimeout) | ||
// Check leader stable, could be a new leader here | ||
leader = c.Leader() | ||
//Write some logs to ensure they replicate | ||
for i := 0; i < 100; i++ { | ||
future := leader.Apply([]byte(fmt.Sprintf("test%d", i)), 0) | ||
if err := future.Error(); err != nil { | ||
t.Fatalf("[ERR] apply err: %v", err) | ||
} | ||
} | ||
c.WaitForReplication(100) | ||
|
||
//Remove the server and add it back as Voter | ||
future = leader.RemoveServer(followerRemoved.localID, 0, 0) | ||
if err := future.Error(); err != nil { | ||
t.Fatalf("err: %v", err) | ||
} | ||
leader.AddVoter(followerRemoved.localID, followerRemoved.localAddr, 0, 0) | ||
|
||
// Wait a while | ||
time.Sleep(c.propagateTimeout * 10) | ||
|
||
//Write some logs to ensure they replicate | ||
for i := 100; i < 200; i++ { | ||
future := leader.Apply([]byte(fmt.Sprintf("test%d", i)), 0) | ||
if err := future.Error(); err != nil { | ||
t.Fatalf("[ERR] apply err: %v", err) | ||
} | ||
} | ||
c.WaitForReplication(200) | ||
|
||
// Check leader stable | ||
newLeader := c.Leader() | ||
if newLeader.leaderID != leader.leaderID { | ||
t.Fatalf("leader changed") | ||
} | ||
} | ||
|
||
// TestRaft_FollowerRemovalNoElection ensures that a leader election is not | ||
// started when a standby is shut down and restarted. | ||
func TestRaft_FollowerRemovalNoElection(t *testing.T) { | ||
|
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.
Do you think it's worth a note or link back to this issue here? I suspect reading this I'd be puzzled about why we allow a non-voter to "disrupt" leaders at all because the nuance involved in this issue is high! Ideally people would view blame before changing this back to ignore votes from non-voters but we could potentially use this comment to flag the non-intuitive behaviour is for a good reason?