Skip to content

Commit

Permalink
raft: error on ignored proposal and wait for EntryConfChange results
Browse files Browse the repository at this point in the history
fixes: etcd-io#43
Signed-off-by: Bogdan Kanivets <[email protected]>
  • Loading branch information
Bogdan Kanivets committed Apr 11, 2023
1 parent 918455b commit 551232a
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 13 deletions.
2 changes: 1 addition & 1 deletion node.go
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ func (n *node) ProposeConfChange(ctx context.Context, cc pb.ConfChangeI) error {
if err != nil {
return err
}
return n.Step(ctx, msg)
return n.stepWait(ctx, msg)
}

func (n *node) step(ctx context.Context, m pb.Message) error {
Expand Down
2 changes: 1 addition & 1 deletion raft.go
Original file line number Diff line number Diff line change
Expand Up @@ -1229,7 +1229,7 @@ func stepLeader(r *raft, m pb.Message) error {

if refused != "" {
r.logger.Infof("%x ignoring conf change %v at config %s: %s", r.id, cc, r.prs.Config, refused)
m.Entries[i] = pb.Entry{Type: pb.EntryNormal}
return ErrProposalDropped
} else {
r.pendingConfIndex = r.raftLog.lastIndex() + uint64(i) + 1
}
Expand Down
15 changes: 4 additions & 11 deletions raft_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3283,24 +3283,17 @@ func TestStepConfig(t *testing.T) {
}

// TestStepIgnoreConfig tests that if raft step the second msgProp in
// EntryConfChange type when the first one is uncommitted, the node will set
// the proposal to noop and keep its original state.
// EntryConfChange type when the first one is uncommitted, the node will drop second msgProp and return ErrProposalDropped.
func TestStepIgnoreConfig(t *testing.T) {
// a raft that cannot make progress
r := newTestRaft(1, 10, 1, newTestMemoryStorage(withPeers(1, 2)))
r.becomeCandidate()
r.becomeLeader()
r.Step(pb.Message{From: 1, To: 1, Type: pb.MsgProp, Entries: []pb.Entry{{Type: pb.EntryConfChange}}})
index := r.raftLog.lastIndex()
pendingConfIndex := r.pendingConfIndex
r.Step(pb.Message{From: 1, To: 1, Type: pb.MsgProp, Entries: []pb.Entry{{Type: pb.EntryConfChange}}})
wents := []pb.Entry{{Type: pb.EntryNormal, Term: 1, Index: 3, Data: nil}}
ents, err := r.raftLog.entries(index+1, noLimit)
if err != nil {
t.Fatalf("unexpected error %v", err)
}
if !reflect.DeepEqual(ents, wents) {
t.Errorf("ents = %+v, want %+v", ents, wents)
err := r.Step(pb.Message{From: 1, To: 1, Type: pb.MsgProp, Entries: []pb.Entry{{Type: pb.EntryConfChange}}})
if err != ErrProposalDropped {
t.Fatalf("Expected %v, got %v", ErrProposalDropped, err)
}
if r.pendingConfIndex != pendingConfIndex {
t.Errorf("pendingConfIndex = %d, want %d", r.pendingConfIndex, pendingConfIndex)
Expand Down

0 comments on commit 551232a

Please sign in to comment.