VOL-4774:openonuAdapterGo: Panic during scale test

Change-Id: Ie41689194d944d533e118a24297b0a9685ade717
diff --git a/internal/pkg/core/device_handler.go b/internal/pkg/core/device_handler.go
index b9cadf0..7f3febf 100755
--- a/internal/pkg/core/device_handler.go
+++ b/internal/pkg/core/device_handler.go
@@ -3750,7 +3750,10 @@
 	// reset like onu rebooted.
 	dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
 	dh.setCollectorIsRunning(true)
+	statsCollectionticker := time.NewTicker((pmmgr.FrequencyGranularity) * time.Second)
+	defer statsCollectionticker.Stop()
 	for {
+
 		select {
 		case <-dh.stopCollector:
 			dh.setCollectorIsRunning(false)
@@ -3773,7 +3776,7 @@
 			}
 
 			return
-		case <-time.After(time.Duration(pmmgr.FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
+		case <-statsCollectionticker.C: // Check every FrequencyGranularity to see if it is time for collecting metrics
 			if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
 				// If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
 				if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
diff --git a/internal/pkg/pmmgr/onu_metrics_manager.go b/internal/pkg/pmmgr/onu_metrics_manager.go
index 3da45b0..43ab2a0 100755
--- a/internal/pkg/pmmgr/onu_metrics_manager.go
+++ b/internal/pkg/pmmgr/onu_metrics_manager.go
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-//Package pmmgr provides the utilities to manage onu metrics
+// Package pmmgr provides the utilities to manage onu metrics
 package pmmgr
 
 import (
@@ -331,6 +331,8 @@
 	isEthernetFrameExtendedPmOperationOngoing     bool
 	isExtendedOmci                                bool
 	maxL2PMGetPayLoadSize                         int
+	onuOpticalMetricstimer                        *time.Timer
+	onuUniStatusMetricstimer                      *time.Timer
 }
 
 // NewOnuMetricsManager returns a new instance of the NewOnuMetricsManager
@@ -406,6 +408,14 @@
 		return nil
 	}
 
+	//Metrics collection timers are initialized with a default timer value,  will be stopped immediately and further
+	//timers are  reset during the actual stats collection begins.
+	metricsManager.onuOpticalMetricstimer = time.NewTimer(DefaultMetricCollectionFrequency)
+	metricsManager.onuOpticalMetricstimer.Stop()
+
+	metricsManager.onuUniStatusMetricstimer = time.NewTimer(DefaultMetricCollectionFrequency)
+	metricsManager.onuUniStatusMetricstimer.Stop()
+
 	logger.Info(ctx, "init-OnuMetricsManager completed", log.Fields{"device-id": metricsManager.deviceID})
 	return &metricsManager
 }
@@ -766,10 +776,12 @@
 		}
 
 		if meInstance != nil {
+			mm.onuOpticalMetricstimer.Reset(mm.pOnuDeviceEntry.GetDevOmciCC().GetMaxOmciTimeoutWithRetries() * time.Second)
 			select {
 			case meAttributes = <-mm.opticalMetricsChan:
-				logger.Debugw(ctx, "received optical metrics", log.Fields{"device-id": mm.deviceID})
-			case <-time.After(mm.pOnuDeviceEntry.GetDevOmciCC().GetMaxOmciTimeoutWithRetries() * time.Second):
+				mm.onuOpticalMetricstimer.Stop()
+				logger.Debugw(ctx, "received optical metrics, stopping the optical metrics collection timer", log.Fields{"device-id": mm.deviceID})
+			case <-mm.onuOpticalMetricstimer.C:
 				logger.Errorw(ctx, "timeout waiting for omci-get response for optical metrics", log.Fields{"device-id": mm.deviceID})
 				// The metrics will be empty in this case
 				break loop
@@ -849,11 +861,13 @@
 			return nil, err
 		}
 		if meInstance != nil {
+			mm.onuUniStatusMetricstimer.Reset(mm.pOnuDeviceEntry.GetDevOmciCC().GetMaxOmciTimeoutWithRetries() * time.Second)
 			// Wait for metrics or timeout
 			select {
 			case meAttributes = <-mm.uniStatusMetricsChan:
-				logger.Debugw(ctx, "received uni-g metrics", log.Fields{"device-id": mm.deviceID})
-			case <-time.After(mm.pOnuDeviceEntry.GetDevOmciCC().GetMaxOmciTimeoutWithRetries() * time.Second):
+				mm.onuUniStatusMetricstimer.Stop()
+				logger.Debugw(ctx, "received uni-g metrics, stopping Onu Uni status metrics timer ", log.Fields{"device-id": mm.deviceID})
+			case <-mm.onuUniStatusMetricstimer.C:
 				logger.Errorw(ctx, "timeout waiting for omci-get response for uni status", log.Fields{"device-id": mm.deviceID})
 				// The metrics could be empty in this case
 				break loop1
@@ -909,11 +923,13 @@
 			return nil, err
 		}
 		if meInstance != nil {
+			mm.onuUniStatusMetricstimer.Reset(mm.pOnuDeviceEntry.GetDevOmciCC().GetMaxOmciTimeoutWithRetries() * time.Second)
 			// Wait for metrics or timeout
 			select {
 			case meAttributes = <-mm.uniStatusMetricsChan:
-				logger.Debugw(ctx, "received pptp metrics", log.Fields{"device-id": mm.deviceID})
-			case <-time.After(mm.pOnuDeviceEntry.GetDevOmciCC().GetMaxOmciTimeoutWithRetries() * time.Second):
+				mm.onuUniStatusMetricstimer.Stop()
+				logger.Debugw(ctx, "received pptp metrics, stopping Onu Uni Status metrics timer ", log.Fields{"device-id": mm.deviceID})
+			case <-mm.onuUniStatusMetricstimer.C:
 				logger.Errorw(ctx, "timeout waiting for omci-get response for uni status", log.Fields{"device-id": mm.deviceID})
 				// The metrics could be empty in this case
 				break loop2
@@ -976,11 +992,13 @@
 			return nil, err
 		}
 		if meInstance != nil {
+			mm.onuUniStatusMetricstimer.Reset(mm.pOnuDeviceEntry.GetDevOmciCC().GetMaxOmciTimeoutWithRetries() * time.Second)
 			// Wait for metrics or timeout
 			select {
 			case meAttributes = <-mm.uniStatusMetricsChan:
-				logger.Debugw(ctx, "received veip metrics", log.Fields{"device-id": mm.deviceID})
-			case <-time.After(mm.pOnuDeviceEntry.GetDevOmciCC().GetMaxOmciTimeoutWithRetries() * time.Second):
+				mm.onuUniStatusMetricstimer.Stop()
+				logger.Debugw(ctx, "received veip metrics, stopping Onu Uni status metrics timer ", log.Fields{"device-id": mm.deviceID})
+			case <-mm.onuUniStatusMetricstimer.C:
 				logger.Errorw(ctx, "timeout waiting for omci-get response for uni status", log.Fields{"device-id": mm.deviceID})
 				// The metrics could be empty in this case
 				break loop3