mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
raft: ensure leader is in ProgressStateReplicate
The leader perpetually kept itself in ProgressStateProbe even though of course it has perfect knowledge of its log. This wasn't usually an issue because it also doesn't care about its own Progress, but it's better to keep this data correctly maintained, especially since this is part of raft.Status and thus becomes visible to applications using the Raft library. (Concretely, in CockroachDB we use the Progress to inform log truncations).
This commit is contained in:
parent
bb25891960
commit
5c209d66d2
@ -750,6 +750,11 @@ func (r *raft) becomeLeader() {
|
||||
r.tick = r.tickHeartbeat
|
||||
r.lead = r.id
|
||||
r.state = StateLeader
|
||||
// Followers enter replicate mode when they've been successfully probed
|
||||
// (perhaps after having received a snapshot as a result). The leader is
|
||||
// trivially in this state. Note that r.reset() has initialized this
|
||||
// progress with the last index already.
|
||||
r.prs[r.id].becomeReplicate()
|
||||
|
||||
// Conservatively set the pendingConfIndex to the last index in the
|
||||
// log. There may or may not be a pending config change, but it's
|
||||
|
@ -267,11 +267,30 @@ func TestProgressResume(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestProgressLeader(t *testing.T) {
|
||||
r := newTestRaft(1, []uint64{1, 2}, 5, 1, NewMemoryStorage())
|
||||
r.becomeCandidate()
|
||||
r.becomeLeader()
|
||||
r.prs[2].becomeReplicate()
|
||||
|
||||
// Send proposals to r1. The first 5 entries should be appended to the log.
|
||||
propMsg := pb.Message{From: 1, To: 1, Type: pb.MsgProp, Entries: []pb.Entry{{Data: []byte("foo")}}}
|
||||
for i := 0; i < 5; i++ {
|
||||
if pr := r.prs[r.id]; pr.State != ProgressStateReplicate || pr.Match != uint64(i+1) || pr.Next != pr.Match+1 {
|
||||
t.Errorf("unexpected progress %v", pr)
|
||||
}
|
||||
if err := r.Step(propMsg); err != nil {
|
||||
t.Fatalf("proposal resulted in error: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestProgressResumeByHeartbeatResp ensures raft.heartbeat reset progress.paused by heartbeat response.
|
||||
func TestProgressResumeByHeartbeatResp(t *testing.T) {
|
||||
r := newTestRaft(1, []uint64{1, 2}, 5, 1, NewMemoryStorage())
|
||||
r.becomeCandidate()
|
||||
r.becomeLeader()
|
||||
|
||||
r.prs[2].Paused = true
|
||||
|
||||
r.Step(pb.Message{From: 1, To: 1, Type: pb.MsgBeat})
|
||||
|
Loading…
x
Reference in New Issue
Block a user