From caf0e64bebfcafa0f1879491b77b8ffb5aa2b67a Mon Sep 17 00:00:00 2001 From: Kevin Wan Date: Sat, 27 Jul 2024 16:27:05 +0800 Subject: [PATCH] chore: optimize lock in discov.etcd (#4275) --- core/discov/internal/registry.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/core/discov/internal/registry.go b/core/discov/internal/registry.go index 0fb2bcac..6b892e08 100644 --- a/core/discov/internal/registry.go +++ b/core/discov/internal/registry.go @@ -30,7 +30,7 @@ var ( // A Registry is a registry that manages the etcd client connections. type Registry struct { clusters map[string]*cluster - lock sync.Mutex + lock sync.RWMutex } // GetRegistry returns a global Registry. @@ -60,12 +60,19 @@ func (r *Registry) Monitor(endpoints []string, key string, l UpdateListener) err func (r *Registry) getCluster(endpoints []string) (c *cluster, exists bool) { clusterKey := getClusterKey(endpoints) - r.lock.Lock() - defer r.lock.Unlock() + r.lock.RLock() c, exists = r.clusters[clusterKey] + r.lock.RUnlock() + if !exists { - c = newCluster(endpoints) - r.clusters[clusterKey] = c + r.lock.Lock() + defer r.lock.Unlock() + // double-check locking + c, exists = r.clusters[clusterKey] + if !exists { + c = newCluster(endpoints) + r.clusters[clusterKey] = c + } } return