|
@@ -83,7 +83,8 @@ type RaftTimer interface {
|
|
|
type apply struct {
|
|
type apply struct {
|
|
|
entries []raftpb.Entry
|
|
entries []raftpb.Entry
|
|
|
snapshot raftpb.Snapshot
|
|
snapshot raftpb.Snapshot
|
|
|
- raftDone <-chan struct{} // rx {} after raft has persisted messages
|
|
|
|
|
|
|
+ // notifyc synchronizes etcd server applies with the raft node
|
|
|
|
|
+ notifyc chan struct{}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
type raftNode struct {
|
|
type raftNode struct {
|
|
@@ -190,11 +191,11 @@ func (r *raftNode) start(rh *raftReadyHandler) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- raftDone := make(chan struct{}, 1)
|
|
|
|
|
|
|
+ notifyc := make(chan struct{}, 1)
|
|
|
ap := apply{
|
|
ap := apply{
|
|
|
entries: rd.CommittedEntries,
|
|
entries: rd.CommittedEntries,
|
|
|
snapshot: rd.Snapshot,
|
|
snapshot: rd.Snapshot,
|
|
|
- raftDone: raftDone,
|
|
|
|
|
|
|
+ notifyc: notifyc,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
updateCommittedIndex(&ap, rh)
|
|
updateCommittedIndex(&ap, rh)
|
|
@@ -227,6 +228,9 @@ func (r *raftNode) start(rh *raftReadyHandler) {
|
|
|
if err := r.storage.SaveSnap(rd.Snapshot); err != nil {
|
|
if err := r.storage.SaveSnap(rd.Snapshot); err != nil {
|
|
|
plog.Fatalf("raft save snapshot error: %v", err)
|
|
plog.Fatalf("raft save snapshot error: %v", err)
|
|
|
}
|
|
}
|
|
|
|
|
+ // etcdserver now claim the snapshot has been persisted onto the disk
|
|
|
|
|
+ notifyc <- struct{}{}
|
|
|
|
|
+
|
|
|
// gofail: var raftAfterSaveSnap struct{}
|
|
// gofail: var raftAfterSaveSnap struct{}
|
|
|
r.raftStorage.ApplySnapshot(rd.Snapshot)
|
|
r.raftStorage.ApplySnapshot(rd.Snapshot)
|
|
|
plog.Infof("raft applied incoming snapshot at index %d", rd.Snapshot.Metadata.Index)
|
|
plog.Infof("raft applied incoming snapshot at index %d", rd.Snapshot.Metadata.Index)
|
|
@@ -240,7 +244,7 @@ func (r *raftNode) start(rh *raftReadyHandler) {
|
|
|
msgs := r.processMessages(rd.Messages)
|
|
msgs := r.processMessages(rd.Messages)
|
|
|
|
|
|
|
|
// now unblocks 'applyAll' that waits on Raft log disk writes before triggering snapshots
|
|
// now unblocks 'applyAll' that waits on Raft log disk writes before triggering snapshots
|
|
|
- raftDone <- struct{}{}
|
|
|
|
|
|
|
+ notifyc <- struct{}{}
|
|
|
|
|
|
|
|
// Candidate or follower needs to wait for all pending configuration
|
|
// Candidate or follower needs to wait for all pending configuration
|
|
|
// changes to be applied before sending messages.
|
|
// changes to be applied before sending messages.
|
|
@@ -259,9 +263,9 @@ func (r *raftNode) start(rh *raftReadyHandler) {
|
|
|
if waitApply {
|
|
if waitApply {
|
|
|
// blocks until 'applyAll' calls 'applyWait.Trigger'
|
|
// blocks until 'applyAll' calls 'applyWait.Trigger'
|
|
|
// to be in sync with scheduled config-change job
|
|
// to be in sync with scheduled config-change job
|
|
|
- // (assume raftDone has cap of 1)
|
|
|
|
|
|
|
+ // (assume notifyc has cap of 1)
|
|
|
select {
|
|
select {
|
|
|
- case raftDone <- struct{}{}:
|
|
|
|
|
|
|
+ case notifyc <- struct{}{}:
|
|
|
case <-r.stopped:
|
|
case <-r.stopped:
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
@@ -271,7 +275,7 @@ func (r *raftNode) start(rh *raftReadyHandler) {
|
|
|
r.transport.Send(msgs)
|
|
r.transport.Send(msgs)
|
|
|
} else {
|
|
} else {
|
|
|
// leader already processed 'MsgSnap' and signaled
|
|
// leader already processed 'MsgSnap' and signaled
|
|
|
- raftDone <- struct{}{}
|
|
|
|
|
|
|
+ notifyc <- struct{}{}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
r.Advance()
|
|
r.Advance()
|