[#2164] network/cache: Separate mutex for addr

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
Evgenii Stratonikov 2022-12-13 16:10:45 +03:00 committed by Anton Nikiforov
parent 0ace28e43d
commit f3caf6acfe

View file

@ -17,6 +17,8 @@ type multiClient struct {
clients map[string]clientcore.Client clients map[string]clientcore.Client
// addrMtx protects addr field. Should not be taken before the mtx.
addrMtx sync.RWMutex
addr network.AddressGroup addr network.AddressGroup
opts ClientCacheOpts opts ClientCacheOpts
@ -74,6 +76,22 @@ func (x *multiClient) updateGroup(group network.AddressGroup) {
return false 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() x.mtx.Lock()
defer x.mtx.Unlock() defer x.mtx.Unlock()
loop: loop:
@ -87,13 +105,19 @@ loop:
} }
// Then add new clients. // Then add new clients.
x.addrMtx.Lock()
x.addr = group x.addr = group
x.addrMtx.Unlock()
} }
func (x *multiClient) iterateClients(ctx context.Context, f func(clientcore.Client) error) error { func (x *multiClient) iterateClients(ctx context.Context, f func(clientcore.Client) error) error {
var firstErr 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 { select {
case <-ctx.Done(): case <-ctx.Done():
firstErr = context.Canceled firstErr = context.Canceled