mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
etcdserver: stop raft loop when receiving stop signal
When it waits for apply to be done, it should stop the loop if it receives stop signal. This helps to print out panic information. Before this PR, if the panic happens when server loop is applying entries, server loop will wait for raft loop to stop forever.
This commit is contained in:
@@ -161,7 +161,11 @@ func (r *raftNode) run() {
|
||||
|
||||
r.s.send(rd.Messages)
|
||||
|
||||
<-apply.done
|
||||
select {
|
||||
case <-apply.done:
|
||||
case <-r.stopped:
|
||||
return
|
||||
}
|
||||
r.Advance()
|
||||
case <-syncC:
|
||||
r.s.sync(defaultSyncTimeout)
|
||||
|
||||
@@ -18,9 +18,11 @@ import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/etcd/pkg/pbutil"
|
||||
"github.com/coreos/etcd/pkg/types"
|
||||
"github.com/coreos/etcd/raft"
|
||||
"github.com/coreos/etcd/raft/raftpb"
|
||||
)
|
||||
|
||||
@@ -141,3 +143,29 @@ func TestCreateConfigChangeEnts(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStopRaftWhenWaitingForApplyDone(t *testing.T) {
|
||||
n := newReadyNode()
|
||||
r := raftNode{
|
||||
Node: n,
|
||||
applyc: make(chan apply),
|
||||
storage: &storageRecorder{},
|
||||
raftStorage: raft.NewMemoryStorage(),
|
||||
transport: &nopTransporter{},
|
||||
}
|
||||
r.s = &EtcdServer{r: r}
|
||||
go r.run()
|
||||
n.readyc <- raft.Ready{}
|
||||
select {
|
||||
case <-r.applyc:
|
||||
case <-time.After(time.Second):
|
||||
t.Fatalf("failed to receive apply struct")
|
||||
}
|
||||
|
||||
r.stopped <- struct{}{}
|
||||
select {
|
||||
case <-r.done:
|
||||
case <-time.After(time.Second):
|
||||
t.Fatalf("failed to stop raft loop")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user