Explorar el Código

Merge pull request #1874 from bdarnell/bootstrap-apply

Pre-apply the bootstrapping ConfChange entries.
Yicheng Qin hace 11 años
padre
commit
f10f7802be
Se han modificado 3 ficheros con 18 adiciones y 2 borrados
  1. 12 0
      raft/node.go
  2. 0 2
      raft/node_test.go
  3. 6 0
      raft/raft.go

+ 12 - 0
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
 	// the invariant that committed < unstable?
 	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)
 	return &n

+ 0 - 2
raft/node_test.go

@@ -324,7 +324,6 @@ func TestNodeStart(t *testing.T) {
 	}
 	storage := NewMemoryStorage()
 	n := StartNode(1, []Peer{{ID: 1}}, 10, 1, storage)
-	n.ApplyConfChange(cc)
 	n.Campaign(ctx)
 	g := <-n.Ready()
 	if !reflect.DeepEqual(g, wants[0]) {
@@ -421,7 +420,6 @@ func TestNodeAdvance(t *testing.T) {
 
 	storage := NewMemoryStorage()
 	n := StartNode(1, []Peer{{ID: 1}}, 10, 1, storage)
-	n.ApplyConfChange(raftpb.ConfChange{Type: raftpb.ConfChangeAddNode, NodeID: 1})
 	n.Campaign(ctx)
 	<-n.Ready()
 	n.Propose(ctx, []byte("foo"))

+ 6 - 0
raft/raft.go

@@ -472,6 +472,12 @@ func (r *raft) handleSnapshot(m pb.Message) {
 func (r *raft) resetPendingConf() { r.pendingConf = false }
 
 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.pendingConf = false
 }