From f3caf6acfee7b93ad8fb829d28463070594b54e4 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Tue, 13 Dec 2022 16:10:45 +0300 Subject: [PATCH] [#2164] network/cache: Separate mutex for addr Signed-off-by: Evgenii Stratonikov --- pkg/network/cache/multi.go | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/pkg/network/cache/multi.go b/pkg/network/cache/multi.go index f60c1e6a8..152b4b92f 100644 --- a/pkg/network/cache/multi.go +++ b/pkg/network/cache/multi.go @@ -17,7 +17,9 @@ type multiClient struct { clients map[string]clientcore.Client - addr network.AddressGroup + // addrMtx protects addr field. Should not be taken before the mtx. + addrMtx sync.RWMutex + addr network.AddressGroup opts ClientCacheOpts } @@ -74,6 +76,22 @@ func (x *multiClient) updateGroup(group network.AddressGroup) { return false }) + x.addrMtx.RLock() + oldGroup := x.addr + x.addrMtx.RUnlock() + if len(oldGroup) == len(cache) { + needUpdate := false + for i := range oldGroup { + if cache[i] != oldGroup[i].String() { + needUpdate = true + break + } + } + if !needUpdate { + return + } + } + x.mtx.Lock() defer x.mtx.Unlock() loop: @@ -87,13 +105,19 @@ loop: } // Then add new clients. + x.addrMtx.Lock() x.addr = group + x.addrMtx.Unlock() } func (x *multiClient) iterateClients(ctx context.Context, f func(clientcore.Client) error) error { var firstErr error - x.addr.IterateAddresses(func(addr network.Address) bool { + x.addrMtx.RLock() + group := x.addr + x.addrMtx.RUnlock() + + group.IterateAddresses(func(addr network.Address) bool { select { case <-ctx.Done(): firstErr = context.Canceled