From 05c2c6641a7cf7588250afec29d1877da8d77fad Mon Sep 17 00:00:00 2001 From: crazycs Date: Wed, 31 Jul 2024 16:21:54 +0800 Subject: [PATCH] fix rpc client panic cause by concurrent close (#1359) (#1395) close issue #1357 --------- Signed-off-by: crazycs520 --- internal/client/client.go | 4 ++++ internal/client/client_test.go | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/internal/client/client.go b/internal/client/client.go index 31d837b57..d5288042b 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -863,6 +863,10 @@ func (c *RPCClient) CloseAddr(addr string) error { func (c *RPCClient) CloseAddrVer(addr string, ver uint64) error { c.Lock() + if c.isClosed { + c.Unlock() + return nil + } conn, ok := c.conns[addr] if ok { if conn.ver <= ver { diff --git a/internal/client/client_test.go b/internal/client/client_test.go index 1491c09f7..ec1533c60 100644 --- a/internal/client/client_test.go +++ b/internal/client/client_test.go @@ -1047,3 +1047,23 @@ func TestFastFailWhenNoAvailableConn(t *testing.T) { require.Equal(t, "no available connections", err.Error()) require.Less(t, time.Since(start), timeout) } + +func TestConcurrentCloseConnPanic(t *testing.T) { + client := NewRPCClient() + addr := "127.0.0.1:6379" + _, err := client.getConnArray(addr, true) + assert.Nil(t, err) + var wg sync.WaitGroup + wg.Add(2) + go func() { + defer wg.Done() + err := client.Close() + assert.Nil(t, err) + }() + go func() { + defer wg.Done() + err := client.CloseAddr(addr) + assert.Nil(t, err) + }() + wg.Wait() +}