raft: make tick unblock and fix potential live lock

This commit is contained in:
Xiang Li 2016-06-16 07:47:19 -07:00
parent 9c78cda088
commit 848f539536
2 changed files with 15 additions and 4 deletions

View File

@ -200,6 +200,7 @@ func StartNode(c *Config, peers []Peer) Node {
} }
n := newNode() n := newNode()
n.logger = c.Logger
go n.run(r) go n.run(r)
return &n return &n
} }
@ -212,6 +213,7 @@ func RestartNode(c *Config) Node {
r := newRaft(c) r := newRaft(c)
n := newNode() n := newNode()
n.logger = c.Logger
go n.run(r) go n.run(r)
return &n return &n
} }
@ -228,6 +230,8 @@ type node struct {
done chan struct{} done chan struct{}
stop chan struct{} stop chan struct{}
status chan chan Status status chan chan Status
logger Logger
} }
func newNode() node { func newNode() node {
@ -238,10 +242,13 @@ func newNode() node {
confstatec: make(chan pb.ConfState), confstatec: make(chan pb.ConfState),
readyc: make(chan Ready), readyc: make(chan Ready),
advancec: make(chan struct{}), advancec: make(chan struct{}),
tickc: make(chan struct{}), // make tickc a buffered chan, so raft node can buffer some ticks when the node
done: make(chan struct{}), // is busy processing raft messages. Raft node will resume process buffered
stop: make(chan struct{}), // ticks when it becomes idle.
status: make(chan chan Status), tickc: make(chan struct{}, 128),
done: make(chan struct{}),
stop: make(chan struct{}),
status: make(chan chan Status),
} }
} }
@ -381,6 +388,8 @@ func (n *node) Tick() {
select { select {
case n.tickc <- struct{}{}: case n.tickc <- struct{}{}:
case <-n.done: case <-n.done:
default:
n.logger.Warningf("A tick missed to fire. Node blocks too long!")
} }
} }

View File

@ -226,6 +226,7 @@ func TestNodeTick(t *testing.T) {
go n.run(r) go n.run(r)
elapsed := r.electionElapsed elapsed := r.electionElapsed
n.Tick() n.Tick()
testutil.WaitSchedule()
n.Stop() n.Stop()
if r.electionElapsed != elapsed+1 { if r.electionElapsed != elapsed+1 {
t.Errorf("elapsed = %d, want %d", r.electionElapsed, elapsed+1) t.Errorf("elapsed = %d, want %d", r.electionElapsed, elapsed+1)
@ -247,6 +248,7 @@ func TestNodeStop(t *testing.T) {
elapsed := r.electionElapsed elapsed := r.electionElapsed
n.Tick() n.Tick()
testutil.WaitSchedule()
n.Stop() n.Stop()
select { select {