raft: compact takes index and nodes parameters

Before this commit, compact always compact log at current appliedindex of raft.
This prevents us from doing non-blocking snapshot since we have to make snapshot
and compact atomically. To prepare for non-blocking snapshot, this commit make
compact supports index and nodes parameters. After completing snapshot, the applier
should call compact with the snapshot index and the nodes at snapshot index to do
a compaction at snapsohot index.
This commit is contained in:
Xiang Li
2014-10-06 10:12:31 +08:00
parent de024ec844
commit 5587e0d73f
6 changed files with 48 additions and 32 deletions

View File

@ -3,6 +3,7 @@ package raft
import (
"errors"
"log"
"reflect"
pb "github.com/coreos/etcd/raft/raftpb"
"github.com/coreos/etcd/third_party/code.google.com/p/go.net/context"
@ -18,11 +19,13 @@ var (
type SoftState struct {
Lead int64
RaftState StateType
Nodes []int64
ShouldStop bool
}
func (a *SoftState) equal(b *SoftState) bool {
return a.Lead == b.Lead && a.RaftState == b.RaftState && a.ShouldStop == b.ShouldStop
nodeeq := reflect.DeepEqual(a.Nodes, b.Nodes)
return a.Lead == b.Lead && a.RaftState == b.RaftState && a.ShouldStop == b.ShouldStop && nodeeq
}
// Ready encapsulates the entries and messages that are ready to read,
@ -56,6 +59,12 @@ type Ready struct {
Messages []pb.Message
}
type compact struct {
index int64
nodes []int64
data []byte
}
func isHardStateEqual(a, b pb.HardState) bool {
return a.Term == b.Term && a.Vote == b.Vote && a.Commit == b.Commit
}
@ -96,7 +105,7 @@ type Node interface {
// Stop performs any necessary termination of the Node
Stop()
// Compact
Compact(d []byte)
Compact(index int64, nodes []int64, d []byte)
}
// StartNode returns a new Node given a unique raft id, a list of raft peers, and
@ -141,7 +150,7 @@ func RestartNode(id int64, peers []int64, election, heartbeat int, snapshot *pb.
type node struct {
propc chan pb.Message
recvc chan pb.Message
compactc chan []byte
compactc chan compact
confc chan pb.ConfChange
readyc chan Ready
tickc chan struct{}
@ -152,7 +161,7 @@ func newNode() node {
return node{
propc: make(chan pb.Message),
recvc: make(chan pb.Message),
compactc: make(chan []byte),
compactc: make(chan compact),
confc: make(chan pb.ConfChange),
readyc: make(chan Ready),
tickc: make(chan struct{}),
@ -200,8 +209,8 @@ func (n *node) run(r *raft) {
r.Step(m)
case m := <-n.recvc:
r.Step(m) // raft never returns an error
case d := <-n.compactc:
r.compact(d)
case c := <-n.compactc:
r.compact(c.index, c.nodes, c.data)
case cc := <-n.confc:
switch cc.Type {
case pb.ConfChangeAddNode:
@ -299,9 +308,9 @@ func (n *node) ApplyConfChange(cc pb.ConfChange) {
}
}
func (n *node) Compact(d []byte) {
func (n *node) Compact(index int64, nodes []int64, d []byte) {
select {
case n.compactc <- d:
case n.compactc <- compact{index, nodes, d}:
case <-n.done:
}
}