From 2b0596f85944ebd276b0c7ac6c8a1ce882357de3 Mon Sep 17 00:00:00 2001 From: mind1949 Date: Fri, 22 Jul 2022 22:12:53 +0800 Subject: [PATCH 1/2] server/etcdserver: check if raftNode has been stopped Signed-off-by: mind1949 --- server/etcdserver/raft.go | 9 ++++++++- server/etcdserver/raft_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/server/etcdserver/raft.go b/server/etcdserver/raft.go index 3db8a57c3b6..704e45a7aac 100644 --- a/server/etcdserver/raft.go +++ b/server/etcdserver/raft.go @@ -377,7 +377,14 @@ func (r *raftNode) apply() chan toApply { } func (r *raftNode) stop() { - r.stopped <- struct{}{} + select { + case r.stopped <- struct{}{}: + // Not already stopped, so trigger it + case <-r.done: + // Has already been stopped - no need to do anything + return + } + // Block until the stop has been acknowledged by start() <-r.done } diff --git a/server/etcdserver/raft_test.go b/server/etcdserver/raft_test.go index 6644d557c73..96969a01d27 100644 --- a/server/etcdserver/raft_test.go +++ b/server/etcdserver/raft_test.go @@ -285,3 +285,30 @@ func TestExpvarWithNoRaftStatus(t *testing.T) { _ = kv.Value.String() }) } + +func TestStopRaftNodeMoreThanOnce(t *testing.T) { + n := newNopReadyNode() + + r := newRaftNode(raftNodeConfig{ + lg: zap.NewExample(), + Node: n, + storage: mockstorage.NewStorageRecorder(""), + raftStorage: raft.NewMemoryStorage(), + transport: newNopTransporter(), + }) + r.start(&raftReadyHandler{}) + + for i := 0; i < 2; i++ { + stopped := make(chan struct{}) + go func() { + r.stop() + close(stopped) + }() + + select { + case <-stopped: + case <-time.After(time.Second): + t.Errorf("*raftNode.stop() is blocked !") + } + } +} From f3bd535747275b478bd2fdbd5ac73c6c96670a8f Mon Sep 17 00:00:00 2001 From: mind1949 Date: Mon, 25 Jul 2022 23:19:29 +0800 Subject: [PATCH 2/2] server/etcdserver: fix test Signed-off-by: mind1949 --- server/etcdserver/raft_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/etcdserver/raft_test.go b/server/etcdserver/raft_test.go index 96969a01d27..d4a9cf40a9a 100644 --- a/server/etcdserver/raft_test.go +++ b/server/etcdserver/raft_test.go @@ -288,9 +288,8 @@ func TestExpvarWithNoRaftStatus(t *testing.T) { func TestStopRaftNodeMoreThanOnce(t *testing.T) { n := newNopReadyNode() - r := newRaftNode(raftNodeConfig{ - lg: zap.NewExample(), + lg: zaptest.NewLogger(t), Node: n, storage: mockstorage.NewStorageRecorder(""), raftStorage: raft.NewMemoryStorage(),