From 5cad4e595cfc0ce83f34e44ace54f9d103d11313 Mon Sep 17 00:00:00 2001 From: Yicheng Qin Date: Mon, 9 Jun 2014 19:37:41 -0700 Subject: [PATCH] raft: add create cluster of itself --- raft/node.go | 24 ++++++++++++++++++++---- raft/node_test.go | 39 ++++++++++++++++++++++++++++----------- 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/raft/node.go b/raft/node.go index c9a686461..2aa0410d2 100644 --- a/raft/node.go +++ b/raft/node.go @@ -13,7 +13,7 @@ type tick int type ConfigCmd struct { Type string - Addr int + Addr int } type Node struct { @@ -28,16 +28,15 @@ type Node struct { addr int } -func New(addr int, peers []int, heartbeat, election tick) *Node { +func New(addr int, heartbeat, election tick) *Node { if election < heartbeat*3 { panic("election is least three times as heartbeat [election: %d, heartbeat: %d]") } n := &Node{ - sm: newStateMachine(addr, peers), heartbeat: heartbeat, election: election, - addr: addr, + addr: addr, } return n @@ -49,6 +48,23 @@ func (n *Node) Propose(data []byte) { n.Step(m) } +func (n *Node) StartCluster() { + if n.sm != nil { + panic("node is started") + } + n.sm = newStateMachine(n.addr, []int{n.addr}) + n.Step(Message{Type: msgHup}) + n.Step(n.confMessage(&ConfigCmd{Type: "add", Addr: n.addr})) + n.Next() +} + +func (n *Node) Start() { + if n.sm != nil { + panic("node is started") + } + n.sm = newStateMachine(n.addr, nil) +} + func (n *Node) Add(addr int) { n.Step(n.confMessage(&ConfigCmd{Type: "add", Addr: addr})) } diff --git a/raft/node_test.go b/raft/node_test.go index 14eb77785..a915b034d 100644 --- a/raft/node_test.go +++ b/raft/node_test.go @@ -10,7 +10,8 @@ const ( ) func TestTickMsgHub(t *testing.T) { - n := New(0, []int{0, 1, 2}, defaultHeartbeat, defaultElection) + n := New(0, defaultHeartbeat, defaultElection) + n.sm = newStateMachine(0, []int{0, 1, 2}) for i := 0; i < defaultElection+1; i++ { n.Tick() @@ -30,7 +31,8 @@ func TestTickMsgHub(t *testing.T) { func TestTickMsgBeat(t *testing.T) { k := 3 - n := New(0, []int{0, 1, 2}, defaultHeartbeat, defaultElection) + n := New(0, defaultHeartbeat, defaultElection) + n.sm = newStateMachine(0, []int{0, 1, 2}) n.Step(Message{Type: msgHup}) // become leader please for _, m := range n.Msgs() { @@ -70,7 +72,8 @@ func TestResetElapse(t *testing.T) { } for i, tt := range tests { - n := New(0, []int{0, 1, 2}, defaultHeartbeat, defaultElection) + n := New(0, defaultHeartbeat, defaultElection) + n.sm = newStateMachine(0, []int{0, 1, 2}) n.sm.term = 2 n.Tick() @@ -85,24 +88,38 @@ func TestResetElapse(t *testing.T) { } } -func TestAdd(t *testing.T) { - n := New(0, []int{0}, defaultHeartbeat, defaultElection) +func TestStartCluster(t *testing.T) { + n := New(0, defaultHeartbeat, defaultElection) + n.StartCluster() - n.sm.becomeCandidate() - n.sm.becomeLeader() + if len(n.sm.ins) != 1 { + t.Errorf("k = %d, want 1", len(n.sm.ins)) + } + if n.sm.addr != 0 { + t.Errorf("addr = %d, want 0", n.sm.addr) + } + if n.sm.state != stateLeader { + t.Errorf("state = %s, want %s", n.sm.state, stateLeader) + } +} + +func TestAdd(t *testing.T) { + n := New(0, defaultHeartbeat, defaultElection) + n.StartCluster() n.Add(1) n.Next() if len(n.sm.ins) != 2 { t.Errorf("k = %d, want 2", len(n.sm.ins)) } + if n.sm.addr != 0 { + t.Errorf("addr = %d, want 0", n.sm.addr) + } } func TestRemove(t *testing.T) { - n := New(0, []int{0}, defaultHeartbeat, defaultElection) - - n.sm.becomeCandidate() - n.sm.becomeLeader() + n := New(0, defaultHeartbeat, defaultElection) + n.StartCluster() n.Add(1) n.Next() n.Remove(0)