From e499d1c81b3aaadb0a1871caa3ace0900313d3c0 Mon Sep 17 00:00:00 2001
From: Joe Zou <yixian.zou@gmail.com>
Date: Mon, 1 Jun 2020 15:16:41 +0800
Subject: [PATCH] lock optimize

---
 registry/etcdv3/registry.go     |  8 +++++++-
 registry/kubernetes/registry.go |  8 +++++++-
 registry/zookeeper/registry.go  | 35 +++++++++++++++++++++++----------
 remoting/zookeeper/client.go    |  6 ------
 4 files changed, 39 insertions(+), 18 deletions(-)

diff --git a/registry/etcdv3/registry.go b/registry/etcdv3/registry.go
index a65d09034..a94352c66 100644
--- a/registry/etcdv3/registry.go
+++ b/registry/etcdv3/registry.go
@@ -119,8 +119,14 @@ func (r *etcdV3Registry) DoUnregister(root string, node string) error {
 }
 
 func (r *etcdV3Registry) CloseAndNilClient() {
-	r.client.Close()
+	r.cltLock.Lock()
+	client := r.client
 	r.client = nil
+	r.cltLock.Unlock()
+	if client == nil {
+		return
+	}
+	client.Close()
 }
 
 func (r *etcdV3Registry) CloseListener() {
diff --git a/registry/kubernetes/registry.go b/registry/kubernetes/registry.go
index 7ee0f6b0e..4c59fc080 100644
--- a/registry/kubernetes/registry.go
+++ b/registry/kubernetes/registry.go
@@ -81,8 +81,14 @@ func (r *kubernetesRegistry) SetClient(client *kubernetes.Client) {
 }
 
 func (r *kubernetesRegistry) CloseAndNilClient() {
-	r.client.Close()
+	r.cltLock.Lock()
+	client := r.client
 	r.client = nil
+	r.cltLock.Unlock()
+	if client == nil {
+		return
+	}
+	client.Close()
 }
 
 func (r *kubernetesRegistry) CloseListener() {
diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go
index 5d5f9e052..fd6ef86e7 100644
--- a/registry/zookeeper/registry.go
+++ b/registry/zookeeper/registry.go
@@ -156,12 +156,15 @@ func (r *zkRegistry) DoRegister(root string, node string) error {
 }
 
 func (r *zkRegistry) DoUnregister(root string, node string) error {
-	r.cltLock.Lock()
-	defer r.cltLock.Unlock()
-	if !r.ZkClient().ZkConnValid() {
+	client := r.client
+	if client == nil {
+		return perrors.New("zk Client is null, can not process registerTempZookeeperNode ")
+	}
+
+	if !client.ZkConnValid() {
 		return perrors.Errorf("zk client is not valid.")
 	}
-	return r.ZkClient().Delete(path.Join(root, node))
+	return client.Delete(path.Join(root, node))
 }
 
 func (r *zkRegistry) DoSubscribe(conf *common.URL) (registry.Listener, error) {
@@ -173,8 +176,15 @@ func (r *zkRegistry) DoUnsubscribe(conf *common.URL) (registry.Listener, error)
 }
 
 func (r *zkRegistry) CloseAndNilClient() {
-	r.client.Close()
+	r.cltLock.Lock()
+	client := r.client
 	r.client = nil
+	r.cltLock.Unlock()
+
+	if client == nil {
+		return
+	}
+	client.Close()
 }
 
 func (r *zkRegistry) ZkClient() *zookeeper.ZookeeperClient {
@@ -202,22 +212,27 @@ func (r *zkRegistry) registerTempZookeeperNode(root string, node string) error {
 	)
 
 	r.cltLock.Lock()
-	defer r.cltLock.Unlock()
-	err = r.client.Create(root)
+	client := r.client
+	r.cltLock.Unlock()
+	if client == nil {
+		return perrors.New("zk Client is null, can not process registerTempZookeeperNode ")
+	}
+
+	err = client.Create(root)
 	if err != nil {
 		logger.Errorf("zk.Create(root{%s}) = err{%v}", root, perrors.WithStack(err))
 		return perrors.WithStack(err)
 	}
 
 	// try to register the node
-	zkPath, err = r.client.RegisterTemp(root, node)
+	zkPath, err = client.RegisterTemp(root, node)
 	if err != nil {
 		logger.Errorf("Register temp node(root{%s}, node{%s}) = error{%v}", root, node, perrors.WithStack(err))
 		if perrors.Cause(err) == zk.ErrNodeExists {
 			// should delete the old node
 			logger.Info("Register temp node failed, try to delete the old and recreate  (root{%s}, node{%s}) , ignore!", root, node)
-			if err = r.client.Delete(zkPath); err == nil {
-				_, err = r.client.RegisterTemp(root, node)
+			if err = client.Delete(zkPath); err == nil {
+				_, err = client.RegisterTemp(root, node)
 			}
 			if err != nil {
 				logger.Errorf("Recreate the temp node failed, (root{%s}, node{%s}) = error{%v}", root, node, perrors.WithStack(err))
diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go
index bd1da5477..59d976f5d 100644
--- a/remoting/zookeeper/client.go
+++ b/remoting/zookeeper/client.go
@@ -419,9 +419,7 @@ func (z *ZookeeperClient) CreateWithValue(basePath string, value []byte) error {
 	for _, str := range strings.Split(basePath, "/")[1:] {
 		tmpPath = path.Join(tmpPath, "/", str)
 		err = errNilZkClientConn
-		z.Lock()
 		conn := z.Conn
-		z.Unlock()
 		if conn != nil {
 			_, err = conn.Create(tmpPath, value, 0, zk.WorldACL(zk.PermAll))
 		}
@@ -446,9 +444,7 @@ func (z *ZookeeperClient) Delete(basePath string) error {
 	)
 
 	err = errNilZkClientConn
-	z.Lock()
 	conn := z.Conn
-	z.Unlock()
 	if conn != nil {
 		err = conn.Delete(basePath, -1)
 	}
@@ -468,9 +464,7 @@ func (z *ZookeeperClient) RegisterTemp(basePath string, node string) (string, er
 	err = errNilZkClientConn
 	data = []byte("")
 	zkPath = path.Join(basePath) + "/" + node
-	z.Lock()
 	conn := z.Conn
-	z.Unlock()
 	if conn != nil {
 		tmpPath, err = conn.Create(zkPath, data, zk.FlagEphemeral, zk.WorldACL(zk.PermAll))
 	}
-- 
GitLab