VOL-2696 Stop monitorKvstoreLiveness goroutine when core is stopped

Change-Id: I648d90b43164d11a54a638da1d0d90d21268ed32
diff --git a/rw_core/core/core.go b/rw_core/core/core.go
index 258850b..0206ee0 100644
--- a/rw_core/core/core.go
+++ b/rw_core/core/core.go
@@ -19,6 +19,7 @@
 import (
 	"context"
 	"fmt"
+	"sync"
 	"time"
 
 	"github.com/opencord/voltha-go/db/model"
@@ -49,7 +50,8 @@
 	localDataRoot     model.Root
 	clusterDataProxy  *model.Proxy
 	localDataProxy    *model.Proxy
-	exitChannel       chan int
+	exitChannel       chan struct{}
+	stopOnce          sync.Once
 	kvClient          kvstore.Client
 	backend           db.Backend
 	kafkaClient       kafka.Client
@@ -67,7 +69,7 @@
 func NewCore(ctx context.Context, id string, cf *config.RWCoreFlags, kvClient kvstore.Client, kafkaClient kafka.Client) *Core {
 	var core Core
 	core.instanceID = id
-	core.exitChannel = make(chan int, 1)
+	core.exitChannel = make(chan struct{})
 	core.config = cf
 	core.kvClient = kvClient
 	core.kafkaClient = kafkaClient
@@ -166,24 +168,25 @@
 
 // Stop brings down core services
 func (core *Core) Stop(ctx context.Context) {
-	log.Info("stopping-adaptercore")
-	if core.exitChannel != nil {
-		core.exitChannel <- 1
-	}
-	// Stop all the started services
-	if core.grpcServer != nil {
-		core.grpcServer.Stop()
-	}
-	if core.logicalDeviceMgr != nil {
-		core.logicalDeviceMgr.stop(ctx)
-	}
-	if core.deviceMgr != nil {
-		core.deviceMgr.stop(ctx)
-	}
-	if core.kmp != nil {
-		core.kmp.Stop()
-	}
-	log.Info("adaptercore-stopped")
+	core.stopOnce.Do(func() {
+		log.Info("stopping-adaptercore")
+		// Signal to the KVStoreMonitor that we are stopping.
+		close(core.exitChannel)
+		// Stop all the started services
+		if core.grpcServer != nil {
+			core.grpcServer.Stop()
+		}
+		if core.logicalDeviceMgr != nil {
+			core.logicalDeviceMgr.stop(ctx)
+		}
+		if core.deviceMgr != nil {
+			core.deviceMgr.stop(ctx)
+		}
+		if core.kmp != nil {
+			core.kmp.Stop()
+		}
+		log.Info("adaptercore-stopped")
+	})
 }
 
 //startGRPCService creates the grpc service handlers, registers it to the grpc server and starts the server
@@ -445,6 +448,7 @@
 
 	// Default state for kvstore is alive for rw_core
 	timeout := core.config.LiveProbeInterval
+loop:
 	for {
 		timeoutTimer := time.NewTimer(timeout)
 		select {
@@ -475,6 +479,9 @@
 				<-timeoutTimer.C
 			}
 
+		case <-core.exitChannel:
+			break loop
+
 		case <-timeoutTimer.C:
 			log.Info("kvstore-perform-liveness-check-on-timeout")