From 846342144852cfc1653beefe481c4e273f7d9f66 Mon Sep 17 00:00:00 2001 From: Blake Mizerany Date: Wed, 3 Sep 2014 13:32:22 -0700 Subject: [PATCH 1/2] raft: remove configuration --- raft/log.go | 4 ---- raft/raft.go | 36 -------------------------------- raft/raft_test.go | 53 ----------------------------------------------- 3 files changed, 93 deletions(-) diff --git a/raft/log.go b/raft/log.go index bd61e3b08..f4f0cb47f 100644 --- a/raft/log.go +++ b/raft/log.go @@ -18,10 +18,6 @@ const ( defaultCompactThreshold = 10000 ) -func isConfig(e pb.Entry) bool { - return e.Type == AddNode || e.Type == RemoveNode -} - type raftLog struct { ents []pb.Entry unstable int64 diff --git a/raft/raft.go b/raft/raft.go index b835f27f7..18f536bb7 100644 --- a/raft/raft.go +++ b/raft/raft.go @@ -108,14 +108,6 @@ type raft struct { // the leader id lead int64 - // pending reconfiguration - configuring bool - - // promotable indicates whether state machine could be promoted. - // New machine has to wait until it has been added to the cluster, or it - // may become the leader of the cluster without it. - promotable bool - elapsed int heartbeatTimeout int electionTimeout int @@ -289,7 +281,6 @@ func (r *raft) becomeFollower(term int64, lead int64) { r.tick = r.tickElection r.lead = lead r.state = stateFollower - r.configuring = false } func (r *raft) becomeCandidate() { @@ -314,13 +305,6 @@ func (r *raft) becomeLeader() { r.tick = r.tickElection r.lead = r.id r.state = stateLeader - - for _, e := range r.raftLog.entries(r.raftLog.committed + 1) { - if isConfig(e) { - r.configuring = true - } - } - r.appendEntry(pb.Entry{Type: Normal, Data: nil}) } @@ -386,19 +370,6 @@ func (r *raft) handleSnapshot(m pb.Message) { } } -func (r *raft) addNode(id int64) { - r.setProgress(id, 0, r.raftLog.lastIndex()+1) - r.configuring = false - if id == r.id { - r.promotable = true - } -} - -func (r *raft) removeNode(id int64) { - r.delProgress(id) - r.configuring = false -} - type stepFunc func(r *raft, m pb.Message) func stepLeader(r *raft, m pb.Message) { @@ -410,12 +381,6 @@ func stepLeader(r *raft, m pb.Message) { panic("unexpected length(entries) of a msgProp") } e := m.Entries[0] - if isConfig(e) { - if r.configuring { - panic("pending conf") - } - r.configuring = true - } r.appendEntry(e) r.bcastAppend() case msgAppResp: @@ -505,7 +470,6 @@ func (r *raft) restore(s pb.Snapshot) bool { r.setProgress(n, 0, r.raftLog.lastIndex()+1) } } - r.configuring = false return true } diff --git a/raft/raft_test.go b/raft/raft_test.go index 960fd06ca..87ada1e5c 100644 --- a/raft/raft_test.go +++ b/raft/raft_test.go @@ -628,59 +628,6 @@ func TestStateTransition(t *testing.T) { } } -func TestConf(t *testing.T) { - sm := newRaft(0, []int64{0}, 0, 0) - sm.becomeCandidate() - sm.becomeLeader() - - sm.Step(pb.Message{From: 0, To: 0, Type: msgProp, Entries: []pb.Entry{{Type: AddNode}}}) - if sm.raftLog.lastIndex() != 2 { - t.Errorf("lastindex = %d, want %d", sm.raftLog.lastIndex(), 1) - } - if !sm.configuring { - t.Errorf("pendingConf = %v, want %v", sm.configuring, true) - } - if sm.raftLog.ents[2].Type != AddNode { - t.Errorf("type = %d, want %d", sm.raftLog.ents[1].Type, AddNode) - } - - // deny the second configuration change request if there is a pending one - paniced := false - defer func() { recover(); paniced = true }() - sm.Step(pb.Message{From: 0, To: 0, Type: msgProp, Entries: []pb.Entry{{Type: AddNode}}}) - if !paniced { - t.Errorf("expected panic") - } - if sm.raftLog.lastIndex() != 2 { - t.Errorf("lastindex = %d, want %d", sm.raftLog.lastIndex(), 1) - } -} - -// Ensures that the new leader sets the pendingConf flag correctly according to -// the uncommitted log entries -func TestConfChangeLeader(t *testing.T) { - tests := []struct { - et int64 - wPending bool - }{ - {Normal, false}, - {AddNode, true}, - {RemoveNode, true}, - } - - for i, tt := range tests { - sm := newRaft(0, []int64{0}, 0, 0) - sm.raftLog = &raftLog{ents: []pb.Entry{{}, {Type: tt.et}}} - - sm.becomeCandidate() - sm.becomeLeader() - - if sm.configuring != tt.wPending { - t.Errorf("#%d: pendingConf = %v, want %v", i, sm.configuring, tt.wPending) - } - } -} - func TestAllServerStepdown(t *testing.T) { tests := []struct { state stateType From 8d9b7b1680a2c108dd9ffda28a5dded107bbd591 Mon Sep 17 00:00:00 2001 From: Blake Mizerany Date: Wed, 3 Sep 2014 15:16:31 -0700 Subject: [PATCH 2/2] raft: remove entry type --- raft/log.go | 8 ----- raft/raft.go | 2 +- raft/raft_test.go | 12 ++++---- raft/raftpb/raft.pb.go | 67 +++++++++++++++--------------------------- raft/raftpb/raft.proto | 1 - 5 files changed, 31 insertions(+), 59 deletions(-) diff --git a/raft/log.go b/raft/log.go index f4f0cb47f..a971b0ab3 100644 --- a/raft/log.go +++ b/raft/log.go @@ -6,14 +6,6 @@ import ( pb "github.com/coreos/etcd/raft/raftpb" ) -const ( - Normal int64 = iota - - ClusterInit - AddNode - RemoveNode -) - const ( defaultCompactThreshold = 10000 ) diff --git a/raft/raft.go b/raft/raft.go index 18f536bb7..be92b0913 100644 --- a/raft/raft.go +++ b/raft/raft.go @@ -305,7 +305,7 @@ func (r *raft) becomeLeader() { r.tick = r.tickElection r.lead = r.id r.state = stateLeader - r.appendEntry(pb.Entry{Type: Normal, Data: nil}) + r.appendEntry(pb.Entry{Data: nil}) } func (r *raft) ReadMessages() []pb.Message { diff --git a/raft/raft_test.go b/raft/raft_test.go index 87ada1e5c..9c7cf4a83 100644 --- a/raft/raft_test.go +++ b/raft/raft_test.go @@ -223,7 +223,7 @@ func TestDuelingCandidates(t *testing.T) { nt.recover() nt.send(pb.Message{From: 2, To: 2, Type: msgHup}) - wlog := &raftLog{ents: []pb.Entry{{}, pb.Entry{Type: Normal, Data: nil, Term: 1, Index: 1}}, committed: 1} + wlog := &raftLog{ents: []pb.Entry{{}, pb.Entry{Data: nil, Term: 1, Index: 1}}, committed: 1} tests := []struct { sm *raft state stateType @@ -275,7 +275,7 @@ func TestCandidateConcede(t *testing.T) { if g := a.Term; g != 1 { t.Errorf("term = %d, want %d", g, 1) } - wantLog := ltoa(&raftLog{ents: []pb.Entry{{}, {Type: Normal, Data: nil, Term: 1, Index: 1}, {Term: 1, Index: 2, Data: data}}, committed: 2}) + wantLog := ltoa(&raftLog{ents: []pb.Entry{{}, {Data: nil, Term: 1, Index: 1}, {Term: 1, Index: 2, Data: data}}, committed: 2}) for i, p := range tt.peers { if sm, ok := p.(*raft); ok { l := ltoa(sm.raftLog) @@ -309,8 +309,8 @@ func TestOldMessages(t *testing.T) { l := &raftLog{ ents: []pb.Entry{ - {}, {Type: Normal, Data: nil, Term: 1, Index: 1}, - {Type: Normal, Data: nil, Term: 2, Index: 2}, {Type: Normal, Data: nil, Term: 3, Index: 3}, + {}, {Data: nil, Term: 1, Index: 1}, + {Data: nil, Term: 2, Index: 2}, {Data: nil, Term: 3, Index: 3}, }, committed: 3, } @@ -364,7 +364,7 @@ func TestProposal(t *testing.T) { wantLog := newLog() if tt.success { - wantLog = &raftLog{ents: []pb.Entry{{}, {Type: Normal, Data: nil, Term: 1, Index: 1}, {Term: 1, Index: 2, Data: data}}, committed: 2} + wantLog = &raftLog{ents: []pb.Entry{{}, {Data: nil, Term: 1, Index: 1}, {Term: 1, Index: 2, Data: data}}, committed: 2} } base := ltoa(wantLog) for i, p := range tt.peers { @@ -398,7 +398,7 @@ func TestProposalByProxy(t *testing.T) { // propose via follower tt.send(pb.Message{From: 1, To: 1, Type: msgProp, Entries: []pb.Entry{{Data: []byte("somedata")}}}) - wantLog := &raftLog{ents: []pb.Entry{{}, {Type: Normal, Data: nil, Term: 1, Index: 1}, {Term: 1, Data: data, Index: 2}}, committed: 2} + wantLog := &raftLog{ents: []pb.Entry{{}, {Data: nil, Term: 1, Index: 1}, {Term: 1, Data: data, Index: 2}}, committed: 2} base := ltoa(wantLog) for i, p := range tt.peers { if sm, ok := p.(*raft); ok { diff --git a/raft/raftpb/raft.pb.go b/raft/raftpb/raft.pb.go index d4fb2dde2..482afbc6e 100644 --- a/raft/raftpb/raft.pb.go +++ b/raft/raftpb/raft.pb.go @@ -18,16 +18,17 @@ package raftpb import proto "code.google.com/p/gogoprotobuf/proto" +import json "encoding/json" import math "math" // discarding unused import gogoproto "code.google.com/p/gogoprotobuf/gogoproto/gogo.pb" import io "io" -import fmt "fmt" import code_google_com_p_gogoprotobuf_proto "code.google.com/p/gogoprotobuf/proto" -// Reference imports to suppress errors if they are not otherwise used. +// Reference proto, json, and math imports to suppress error if they are not otherwise used. var _ = proto.Marshal +var _ = &json.SyntaxError{} var _ = math.Inf type Info struct { @@ -40,7 +41,6 @@ func (m *Info) String() string { return proto.CompactTextString(m) } func (*Info) ProtoMessage() {} type Entry struct { - Type int64 `protobuf:"varint,1,req,name=type" json:"type"` Term int64 `protobuf:"varint,2,req,name=term" json:"term"` Index int64 `protobuf:"varint,3,req,name=index" json:"index"` Data []byte `protobuf:"bytes,4,opt,name=data" json:"data"` @@ -115,7 +115,7 @@ func (m *Info) Unmarshal(data []byte) error { switch fieldNum { case 1: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } for shift := uint(0); ; shift += 7 { if index >= l { @@ -170,24 +170,9 @@ func (m *Entry) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - for shift := uint(0); ; shift += 7 { - if index >= l { - return io.ErrUnexpectedEOF - } - b := data[index] - index++ - m.Type |= (int64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } case 2: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Term", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } for shift := uint(0); ; shift += 7 { if index >= l { @@ -202,7 +187,7 @@ func (m *Entry) Unmarshal(data []byte) error { } case 3: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } for shift := uint(0); ; shift += 7 { if index >= l { @@ -217,7 +202,7 @@ func (m *Entry) Unmarshal(data []byte) error { } case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } var byteLen int for shift := uint(0); ; shift += 7 { @@ -281,7 +266,7 @@ func (m *Snapshot) Unmarshal(data []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } var byteLen int for shift := uint(0); ; shift += 7 { @@ -303,7 +288,7 @@ func (m *Snapshot) Unmarshal(data []byte) error { index = postIndex case 2: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Nodes", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } var v int64 for shift := uint(0); ; shift += 7 { @@ -320,7 +305,7 @@ func (m *Snapshot) Unmarshal(data []byte) error { m.Nodes = append(m.Nodes, v) case 3: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } for shift := uint(0); ; shift += 7 { if index >= l { @@ -335,7 +320,7 @@ func (m *Snapshot) Unmarshal(data []byte) error { } case 4: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Term", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } for shift := uint(0); ; shift += 7 { if index >= l { @@ -392,7 +377,7 @@ func (m *Message) Unmarshal(data []byte) error { switch fieldNum { case 1: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } for shift := uint(0); ; shift += 7 { if index >= l { @@ -407,7 +392,7 @@ func (m *Message) Unmarshal(data []byte) error { } case 2: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field To", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } for shift := uint(0); ; shift += 7 { if index >= l { @@ -422,7 +407,7 @@ func (m *Message) Unmarshal(data []byte) error { } case 3: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field From", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } for shift := uint(0); ; shift += 7 { if index >= l { @@ -437,7 +422,7 @@ func (m *Message) Unmarshal(data []byte) error { } case 4: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Term", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } for shift := uint(0); ; shift += 7 { if index >= l { @@ -452,7 +437,7 @@ func (m *Message) Unmarshal(data []byte) error { } case 5: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field LogTerm", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } for shift := uint(0); ; shift += 7 { if index >= l { @@ -467,7 +452,7 @@ func (m *Message) Unmarshal(data []byte) error { } case 6: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } for shift := uint(0); ; shift += 7 { if index >= l { @@ -482,7 +467,7 @@ func (m *Message) Unmarshal(data []byte) error { } case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Entries", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } var msglen int for shift := uint(0); ; shift += 7 { @@ -505,7 +490,7 @@ func (m *Message) Unmarshal(data []byte) error { index = postIndex case 8: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Commit", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } for shift := uint(0); ; shift += 7 { if index >= l { @@ -520,7 +505,7 @@ func (m *Message) Unmarshal(data []byte) error { } case 9: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Snapshot", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } var msglen int for shift := uint(0); ; shift += 7 { @@ -586,7 +571,7 @@ func (m *State) Unmarshal(data []byte) error { switch fieldNum { case 1: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Term", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } for shift := uint(0); ; shift += 7 { if index >= l { @@ -601,7 +586,7 @@ func (m *State) Unmarshal(data []byte) error { } case 2: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Vote", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } for shift := uint(0); ; shift += 7 { if index >= l { @@ -616,7 +601,7 @@ func (m *State) Unmarshal(data []byte) error { } case 3: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Commit", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } for shift := uint(0); ; shift += 7 { if index >= l { @@ -631,7 +616,7 @@ func (m *State) Unmarshal(data []byte) error { } case 4: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field LastIndex", wireType) + return code_google_com_p_gogoprotobuf_proto.ErrWrongType } for shift := uint(0); ; shift += 7 { if index >= l { @@ -679,7 +664,6 @@ func (m *Info) Size() (n int) { func (m *Entry) Size() (n int) { var l int _ = l - n += 1 + sovRaft(uint64(m.Type)) n += 1 + sovRaft(uint64(m.Term)) n += 1 + sovRaft(uint64(m.Index)) l = len(m.Data) @@ -793,9 +777,6 @@ func (m *Entry) MarshalTo(data []byte) (n int, err error) { _ = i var l int _ = l - data[i] = 0x8 - i++ - i = encodeVarintRaft(data, i, uint64(m.Type)) data[i] = 0x10 i++ i = encodeVarintRaft(data, i, uint64(m.Term)) diff --git a/raft/raftpb/raft.proto b/raft/raftpb/raft.proto index 73eec35df..1075524fd 100644 --- a/raft/raftpb/raft.proto +++ b/raft/raftpb/raft.proto @@ -12,7 +12,6 @@ message Info { } message Entry { - required int64 type = 1 [(gogoproto.nullable) = false]; required int64 term = 2 [(gogoproto.nullable) = false]; required int64 index = 3 [(gogoproto.nullable) = false]; optional bytes data = 4 [(gogoproto.nullable) = false];