Merge pull request #1874 from bdarnell/bootstrap-apply
Pre-apply the bootstrapping ConfChange entries.release-2.0
commit
f10f7802be
12
raft/node.go
12
raft/node.go
|
@ -150,6 +150,18 @@ func StartNode(id uint64, peers []Peer, election, heartbeat int, storage Storage
|
||||||
// TODO(bdarnell): These entries are still unstable; do we need to preserve
|
// TODO(bdarnell): These entries are still unstable; do we need to preserve
|
||||||
// the invariant that committed < unstable?
|
// the invariant that committed < unstable?
|
||||||
r.raftLog.committed = r.raftLog.lastIndex()
|
r.raftLog.committed = r.raftLog.lastIndex()
|
||||||
|
// Now apply them, mainly so that the application can call Campaign
|
||||||
|
// immediately after StartNode in tests. Note that these nodes will
|
||||||
|
// be added to raft twice: here and when the application's Ready
|
||||||
|
// loop calls ApplyConfChange. The calls to addNode must come after
|
||||||
|
// all calls to raftLog.append so progress.next is set after these
|
||||||
|
// bootstrapping entries (it is an error if we try to append these
|
||||||
|
// entries since they have already been committed).
|
||||||
|
// We do not set raftLog.applied so the application will be able
|
||||||
|
// to observe all conf changes via Ready.CommittedEntries.
|
||||||
|
for _, peer := range peers {
|
||||||
|
r.addNode(peer.ID)
|
||||||
|
}
|
||||||
|
|
||||||
go n.run(r)
|
go n.run(r)
|
||||||
return &n
|
return &n
|
||||||
|
|
|
@ -324,7 +324,6 @@ func TestNodeStart(t *testing.T) {
|
||||||
}
|
}
|
||||||
storage := NewMemoryStorage()
|
storage := NewMemoryStorage()
|
||||||
n := StartNode(1, []Peer{{ID: 1}}, 10, 1, storage)
|
n := StartNode(1, []Peer{{ID: 1}}, 10, 1, storage)
|
||||||
n.ApplyConfChange(cc)
|
|
||||||
n.Campaign(ctx)
|
n.Campaign(ctx)
|
||||||
g := <-n.Ready()
|
g := <-n.Ready()
|
||||||
if !reflect.DeepEqual(g, wants[0]) {
|
if !reflect.DeepEqual(g, wants[0]) {
|
||||||
|
@ -421,7 +420,6 @@ func TestNodeAdvance(t *testing.T) {
|
||||||
|
|
||||||
storage := NewMemoryStorage()
|
storage := NewMemoryStorage()
|
||||||
n := StartNode(1, []Peer{{ID: 1}}, 10, 1, storage)
|
n := StartNode(1, []Peer{{ID: 1}}, 10, 1, storage)
|
||||||
n.ApplyConfChange(raftpb.ConfChange{Type: raftpb.ConfChangeAddNode, NodeID: 1})
|
|
||||||
n.Campaign(ctx)
|
n.Campaign(ctx)
|
||||||
<-n.Ready()
|
<-n.Ready()
|
||||||
n.Propose(ctx, []byte("foo"))
|
n.Propose(ctx, []byte("foo"))
|
||||||
|
|
|
@ -472,6 +472,12 @@ func (r *raft) handleSnapshot(m pb.Message) {
|
||||||
func (r *raft) resetPendingConf() { r.pendingConf = false }
|
func (r *raft) resetPendingConf() { r.pendingConf = false }
|
||||||
|
|
||||||
func (r *raft) addNode(id uint64) {
|
func (r *raft) addNode(id uint64) {
|
||||||
|
if _, ok := r.prs[id]; ok {
|
||||||
|
// Ignore any redundant addNode calls (which can happen because the
|
||||||
|
// initial bootstrapping entries are applied twice).
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
r.setProgress(id, 0, r.raftLog.lastIndex()+1)
|
r.setProgress(id, 0, r.raftLog.lastIndex()+1)
|
||||||
r.pendingConf = false
|
r.pendingConf = false
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue