mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
raft: make tick unblock and fix potential live lock
This commit is contained in:
parent
9c78cda088
commit
848f539536
17
raft/node.go
17
raft/node.go
@ -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!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user