From d024a3c080d0b5fcdfaadc100e261d300a455ba3 Mon Sep 17 00:00:00 2001
From: Ming Deng <mindeng@ebay.com>
Date: Sun, 15 Dec 2019 13:29:50 +0800
Subject: [PATCH] Fix BUG: The RegistryConfigurationListener will be closed
 twice sometimes

---
 .../impl/tps_limiter_method_service_test.go   |  2 +-
 registry/zookeeper/listener.go                | 19 +++++++++----------
 2 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/filter/impl/tps/impl/tps_limiter_method_service_test.go b/filter/impl/tps/impl/tps_limiter_method_service_test.go
index a21d34283..e747d4682 100644
--- a/filter/impl/tps/impl/tps_limiter_method_service_test.go
+++ b/filter/impl/tps/impl/tps_limiter_method_service_test.go
@@ -50,7 +50,7 @@ func TestMethodServiceTpsLimiterImpl_IsAllowable_Only_Service_Level(t *testing.T
 	mockStrategyImpl.EXPECT().IsAllowable().Return(true).Times(1)
 
 	extension.SetTpsLimitStrategy(constant.DEFAULT_KEY, &mockStrategyCreator{
-		rate:     40,
+		rate:     20,
 		interval: 60000,
 		t:        t,
 		strategy: mockStrategyImpl,
diff --git a/registry/zookeeper/listener.go b/registry/zookeeper/listener.go
index a464da88e..53a592609 100644
--- a/registry/zookeeper/listener.go
+++ b/registry/zookeeper/listener.go
@@ -20,6 +20,7 @@ package zookeeper
 import (
 	"context"
 	"strings"
+	"sync"
 )
 
 import (
@@ -71,10 +72,11 @@ func (l *RegistryDataListener) DataChange(eventType remoting.Event) bool {
 }
 
 type RegistryConfigurationListener struct {
-	client   *zk.ZookeeperClient
-	registry *zkRegistry
-	events   chan *config_center.ConfigChangeEvent
-	isClosed bool
+	client    *zk.ZookeeperClient
+	registry  *zkRegistry
+	events    chan *config_center.ConfigChangeEvent
+	isClosed  bool
+	closeOnce sync.Once
 }
 
 func NewRegistryConfigurationListener(client *zk.ZookeeperClient, reg *zkRegistry) *RegistryConfigurationListener {
@@ -110,14 +112,11 @@ func (l *RegistryConfigurationListener) Next() (*registry.ServiceEvent, error) {
 	}
 }
 func (l *RegistryConfigurationListener) Close() {
-	if l.registry.IsAvailable() {
-		/**
-		 * if the registry is not available, it means that the registry has been destroy
-		 * so we don't need to call Done(), or it will cause the negative count panic for registry.wg
-		 */
+	// ensure that the listener will be closed at most once.
+	l.closeOnce.Do(func() {
 		l.isClosed = true
 		l.registry.wg.Done()
-	}
+	})
 }
 
 func (l *RegistryConfigurationListener) valid() bool {
-- 
GitLab