|
@@ -951,11 +951,20 @@ func (s *EtcdServer) publish(timeout time.Duration) {
|
|
|
|
|
|
|
|
// TODO: move this function into raft.go
|
|
// TODO: move this function into raft.go
|
|
|
func (s *EtcdServer) send(ms []raftpb.Message) {
|
|
func (s *EtcdServer) send(ms []raftpb.Message) {
|
|
|
- for i := range ms {
|
|
|
|
|
|
|
+ sentAppResp := false
|
|
|
|
|
+ for i := len(ms) - 1; i >= 0; i-- {
|
|
|
if s.cluster.IsIDRemoved(types.ID(ms[i].To)) {
|
|
if s.cluster.IsIDRemoved(types.ID(ms[i].To)) {
|
|
|
ms[i].To = 0
|
|
ms[i].To = 0
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if ms[i].Type == raftpb.MsgAppResp {
|
|
|
|
|
+ if sentAppResp {
|
|
|
|
|
+ ms[i].To = 0
|
|
|
|
|
+ } else {
|
|
|
|
|
+ sentAppResp = true
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if ms[i].Type == raftpb.MsgSnap {
|
|
if ms[i].Type == raftpb.MsgSnap {
|
|
|
// There are two separate data store: the store for v2, and the KV for v3.
|
|
// There are two separate data store: the store for v2, and the KV for v3.
|
|
|
// The msgSnap only contains the most recent snapshot of store without KV.
|
|
// The msgSnap only contains the most recent snapshot of store without KV.
|