From 38e4ef09e02d2e1ef4a1a3b1f813783f8a1b7295 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Thu, 13 Feb 2014 08:45:36 +0100 Subject: [PATCH] Use a single Timer instead of two threads It turns out that we really want to have the aging and collection bound to a common timeline, so let's combine them. This will give us the opportunity to perform mark&sweep in future. Furthermore we use the threads only for periodic tasks, so let's convert to a Timer with TimerTasks. This will allow us more flexibility going forward, for example allowing NodeStatisticsHandlers to manage how often they wish to collect individual statistics. Change-Id: Ie2cd0e4e7391e1175a8927773f85278b80f16c48 Signed-off-by: Robert Varga --- .../manager/MultipartMessageManager.java | 2 +- .../manager/NodeStatisticsHandler.java | 2 +- .../manager/StatisticsProvider.java | 62 ++++++------------- 3 files changed, 21 insertions(+), 45 deletions(-) diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MultipartMessageManager.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MultipartMessageManager.java index 02b397e78f..2201cb3930 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MultipartMessageManager.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MultipartMessageManager.java @@ -129,7 +129,7 @@ public class MultipartMessageManager { private static Long getExpiryTime(){ return System.nanoTime() + TimeUnit.MILLISECONDS.toNanos( - StatisticsProvider.STATS_THREAD_EXECUTION_TIME*NUMBER_OF_WAIT_CYCLES); + StatisticsProvider.STATS_COLLECTION_MILLIS*NUMBER_OF_WAIT_CYCLES); } public enum StatsRequestType{ diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java index 5ef4b36563..326da07c73 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java @@ -691,7 +691,7 @@ public final class NodeStatisticsHandler implements AutoCloseable { private static Long getExpiryTime(){ final long now = System.nanoTime(); - return now + TimeUnit.MILLISECONDS.toNanos(StatisticsProvider.STATS_THREAD_EXECUTION_TIME * NUMBER_OF_WAIT_CYCLES); + return now + TimeUnit.MILLISECONDS.toNanos(StatisticsProvider.STATS_COLLECTION_MILLIS * NUMBER_OF_WAIT_CYCLES); } public synchronized void cleanStaleStatistics(){ diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java index 3b9b4dc39e..7432db74eb 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java @@ -8,10 +8,13 @@ package org.opendaylight.controller.md.statistics.manager; import java.util.Collection; +import java.util.Timer; +import java.util.TimerTask; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType; import org.opendaylight.controller.sal.binding.api.NotificationProviderService; @@ -88,12 +91,13 @@ import com.google.common.base.Preconditions; * */ public class StatisticsProvider implements AutoCloseable { - public static final int STATS_THREAD_EXECUTION_TIME= 15000; + public static final long STATS_COLLECTION_MILLIS = TimeUnit.SECONDS.toMillis(15); private static final Logger spLogger = LoggerFactory.getLogger(StatisticsProvider.class); private final ConcurrentMap handlers = new ConcurrentHashMap<>(); private final MultipartMessageManager multipartMessageManager = new MultipartMessageManager(); + private final Timer timer = new Timer("statistics-manager", true); private final DataProviderService dps; private OpendaylightGroupStatisticsService groupStatsService; @@ -110,11 +114,6 @@ public class StatisticsProvider implements AutoCloseable { private StatisticsUpdateHandler statsUpdateHandler; - private Thread statisticsRequesterThread; - - private Thread statisticsAgerThread; - - public StatisticsProvider(final DataProviderService dataService) { this.dps = Preconditions.checkNotNull(dataService); } @@ -152,49 +151,26 @@ public class StatisticsProvider implements AutoCloseable { statsUpdateHandler = new StatisticsUpdateHandler(StatisticsProvider.this); registerDataStoreUpdateListener(dbs); - statisticsRequesterThread = new Thread( new Runnable(){ - + timer.schedule(new TimerTask() { @Override public void run() { - while(true){ - try { - statsRequestSender(); + try { + // Send stats requests + statsRequestSender(); - Thread.sleep(STATS_THREAD_EXECUTION_TIME); - }catch (Exception e){ - spLogger.error("Exception occurred while sending stats request : {}",e); + // Perform cleanup + for(NodeStatisticsHandler nodeStatisticsAger : handlers.values()){ + nodeStatisticsAger.cleanStaleStatistics(); } - } - } - }); - - spLogger.debug("Statistics requester thread started with timer interval : {}",STATS_THREAD_EXECUTION_TIME); - statisticsRequesterThread.start(); - - statisticsAgerThread = new Thread( new Runnable(){ - - @Override - public void run() { - while(true){ - try { - for(NodeStatisticsHandler nodeStatisticsAger : handlers.values()){ - nodeStatisticsAger.cleanStaleStatistics(); - } - multipartMessageManager.cleanStaleTransactionIds(); - - Thread.sleep(STATS_THREAD_EXECUTION_TIME); - }catch (Exception e){ - spLogger.error("Exception occurred while sending stats request : {}",e); - } + multipartMessageManager.cleanStaleTransactionIds(); + } catch (RuntimeException e) { + spLogger.warn("Failed to request statistics", e); } } - }); - - spLogger.debug("Statistics ager thread started with timer interval : {}",STATS_THREAD_EXECUTION_TIME); - - statisticsAgerThread.start(); + }, 0, STATS_COLLECTION_MILLIS); + spLogger.debug("Statistics timer task with timer interval : {}ms", STATS_COLLECTION_MILLIS); spLogger.info("Statistics Provider started."); } @@ -465,13 +441,13 @@ public class StatisticsProvider implements AutoCloseable { try { if (this.listenerRegistration != null) { this.listenerRegistration.close(); - this.statisticsRequesterThread.destroy(); - this.statisticsAgerThread.destroy(); + this.listenerRegistration = null; } if (this.flowCapableTrackerRegistration != null) { this.flowCapableTrackerRegistration.close(); this.flowCapableTrackerRegistration = null; } + timer.cancel(); } catch (Exception e) { spLogger.warn("Failed to stop Statistics Provider completely", e); } finally { -- 2.36.6