Browse Source

raft: add Load

Yicheng Qin 11 years ago
parent
commit
2bd74bc328
3 changed files with 52 additions and 0 deletions
  1. 6 0
      raft/node.go
  2. 29 0
      raft/node_test.go
  3. 17 0
      raft/raft.go

+ 6 - 0
raft/node.go

@@ -219,3 +219,9 @@ func (n *Node) UnstableState() State {
 	n.sm.clearState()
 	return s
 }
+
+// Load loads saved info and recovers the node.
+// It should only be called for new node.
+func (n *Node) Load(ents []Entry, state State) {
+	n.sm.load(ents, state)
+}

+ 29 - 0
raft/node_test.go

@@ -188,6 +188,35 @@ func TestDenial(t *testing.T) {
 	}
 }
 
+func TestLoad(t *testing.T) {
+	ents := []Entry{{Term: 1}, {Term: 2}, {Term: 3}}
+	state := State{Term: 500, Vote: 1, Commit: 3}
+
+	n := New(0, defaultHeartbeat, defaultElection)
+	n.Load(ents, state)
+	if g := n.Next(); !reflect.DeepEqual(g, ents) {
+		t.Errorf("ents = %+v, want %+v", g, ents)
+	}
+	if g := n.sm.term; g.Get() != state.Term {
+		t.Errorf("term = %d, want %d", g, state.Term)
+	}
+	if g := n.sm.vote; g != state.Vote {
+		t.Errorf("vote = %d, want %d", g, state.Vote)
+	}
+	if g := n.sm.raftLog.committed; g != state.Commit {
+		t.Errorf("committed = %d, want %d", g, state.Commit)
+	}
+	if g := n.UnstableEnts(); g != nil {
+		t.Errorf("unstableEnts = %+v, want nil", g)
+	}
+	if g := n.UnstableState(); !reflect.DeepEqual(g, state) {
+		t.Errorf("unstableState = %+v, want %+v", g, state)
+	}
+	if g := n.Msgs(); len(g) != 0 {
+		t.Errorf("#%d: len(msgs) = %d, want 0", len(g))
+	}
+}
+
 func dictate(n *Node) *Node {
 	n.Step(Message{From: n.Id(), Type: msgHup})
 	n.InitCluster(0xBEEF)

+ 17 - 0
raft/raft.go

@@ -589,3 +589,20 @@ func (sm *stateMachine) setState(vote, term, commit int64) {
 	sm.unstableState.Term = term
 	sm.unstableState.Commit = commit
 }
+
+func (sm *stateMachine) load(ents []Entry, state State) {
+	sm.loadEnts(ents)
+	sm.loadState(state)
+}
+
+func (sm *stateMachine) loadEnts(ents []Entry) {
+	sm.raftLog.append(sm.raftLog.lastIndex(), ents...)
+}
+
+func (sm *stateMachine) loadState(state State) {
+	sm.term.Set(state.Term)
+	sm.vote = state.Vote
+	sm.raftLog.unstable = state.Commit + 1
+	sm.raftLog.committed = state.Commit
+	sm.saveState()
+}