From 2bd74bc3284472df3bd5ddcc55fb182a49714d68 Mon Sep 17 00:00:00 2001 From: Yicheng Qin Date: Fri, 25 Jul 2014 15:15:00 -0700 Subject: [PATCH] raft: add Load --- raft/node.go | 6 ++++++ raft/node_test.go | 29 +++++++++++++++++++++++++++++ raft/raft.go | 17 +++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/raft/node.go b/raft/node.go index da2c97d7b..f0d5fee41 100644 --- a/raft/node.go +++ b/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) +} diff --git a/raft/node_test.go b/raft/node_test.go index c61921e7e..bfee6ff2e 100644 --- a/raft/node_test.go +++ b/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) diff --git a/raft/raft.go b/raft/raft.go index 0502af4eb..eb4f71bfb 100644 --- a/raft/raft.go +++ b/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() +}