Skip to content

Commit

Permalink
raft: clarify successful snapshot path
Browse files Browse the repository at this point in the history
Receiving a non-rejecting MsgApp is a standard way of learning that
a follower has successfully applied a snapshot. Confusingly this
was dubbed as "aborting a snapshot" by the code.
  • Loading branch information
tbg committed Jun 8, 2019
1 parent 84f7042 commit e558363
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 10 deletions.
8 changes: 6 additions & 2 deletions raft/raft.go
Original file line number Diff line number Diff line change
Expand Up @@ -1044,8 +1044,8 @@ func stepLeader(r *raft, m pb.Message) error {
switch {
case pr.State == tracker.StateProbe:
pr.BecomeReplicate()
case pr.State == tracker.StateSnapshot && pr.NeedSnapshotAbort():
r.logger.Debugf("%x snapshot aborted, resumed sending replication messages to %x [%s]", r.id, m.From, pr)
case pr.State == tracker.StateSnapshot && pr.Match >= pr.PendingSnapshot:
r.logger.Debugf("%x recovered from needing snapshot, resumed sending replication messages to %x [%s]", r.id, m.From, pr)
// Transition back to replicating state via probing state
// (which takes the snapshot into account). If we didn't
// move to replicating state, that would only happen with
Expand Down Expand Up @@ -1112,6 +1112,10 @@ func stepLeader(r *raft, m pb.Message) error {
if pr.State != tracker.StateSnapshot {
return nil
}
// TODO(tbg): this code is very similar to the snapshot handling in
// MsgAppResp above. In fact, the code there is more correct than the
// code here and should likely be updated to match (or even better, the
// logic pulled into a newly created Progress state machine handler).
if !m.Reject {
pr.BecomeProbe()
r.logger.Debugf("%x snapshot succeeded, resumed sending replication messages to %x [%s]", r.id, m.From, pr)
Expand Down
15 changes: 7 additions & 8 deletions raft/tracker/progress.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,13 @@ package tracker

import "fmt"

// Progress represents a follower’s progress in the view of the leader. Leader maintains
// progresses of all followers, and sends entries to the follower based on its progress.
// Progress represents a follower’s progress in the view of the leader. Leader
// maintains progresses of all followers, and sends entries to the follower
// based on its progress.
//
// NB(tbg): Progress is basically a state machine whose transitions are mostly
// strewn around `*raft.raft`. Additionally, some fields are only used when in a
// certain State. All of this isn't ideal.
type Progress struct {
Match, Next uint64
// State defines how the leader should interact with the follower.
Expand Down Expand Up @@ -196,12 +201,6 @@ func (pr *Progress) IsPaused() bool {
}
}

// needSnapshotAbort returns true if snapshot progress's Match
// is equal or higher than the pendingSnapshot.
func (pr *Progress) NeedSnapshotAbort() bool {
return pr.State == StateSnapshot && pr.Match >= pr.PendingSnapshot
}

func (pr *Progress) String() string {
return fmt.Sprintf("next = %d, match = %d, state = %s, waiting = %v, pendingSnapshot = %d, recentActive = %v, isLearner = %v",
pr.Next, pr.Match, pr.State, pr.IsPaused(), pr.PendingSnapshot, pr.RecentActive, pr.IsLearner)
Expand Down

0 comments on commit e558363

Please sign in to comment.