Merge "Introduce DataStoreJobCoordinator counters"
authorSam Hague <shague@redhat.com>
Thu, 8 Dec 2016 17:59:45 +0000 (17:59 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 8 Dec 2016 17:59:45 +0000 (17:59 +0000)
mdsalutil/mdsalutil-api/pom.xml
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/DataStoreJobCoordinator.java
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/DataStoreJobCoordinatorCounters.java [new file with mode: 0644]

index c34eb32ed6abe19c98836a9393fac1929040ec0d..e83967bde08defbf0eb5fdfcb6d410dfab4cc2c8 100644 (file)
@@ -61,6 +61,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <artifactId>utils.config</artifactId>
     <version>${genius.ovsdb.version}</version>
   </dependency>
+  <dependency>
+      <groupId>org.opendaylight.infrautils</groupId>
+      <artifactId>counters-api</artifactId>
+      <version>${genius.infrautils.version}</version>
+  </dependency>
   <dependency>
       <groupId>org.opendaylight.infrautils</groupId>
       <artifactId>inject</artifactId>
index 7221b2b599a21f8a9c7dc703d8c3dddb8b81e1ae..bfc6f0fb1b5290fadcf156bfe522ffc604ea259d 100755 (executable)
@@ -14,6 +14,8 @@ import com.google.common.util.concurrent.ListenableFuture;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executors;
@@ -61,20 +63,16 @@ public class DataStoreJobCoordinator {
         new Thread(new JobQueueHandler()).start();
     }
 
-    public void enqueueJob(String key,
-            Callable<List<ListenableFuture<Void>>> mainWorker) {
+    public void enqueueJob(String key, Callable<List<ListenableFuture<Void>>> mainWorker) {
         enqueueJob(key, mainWorker, null, 0);
     }
 
-    public void enqueueJob(String key,
-            Callable<List<ListenableFuture<Void>>> mainWorker,
+    public void enqueueJob(String key, Callable<List<ListenableFuture<Void>>> mainWorker,
             RollbackCallable rollbackWorker) {
         enqueueJob(key, mainWorker, rollbackWorker, 0);
     }
 
-    public void enqueueJob(String key,
-            Callable<List<ListenableFuture<Void>>> mainWorker,
-            int maxRetries) {
+    public void enqueueJob(String key, Callable<List<ListenableFuture<Void>>> mainWorker, int maxRetries) {
         enqueueJob(key, mainWorker, null, maxRetries);
     }
 
@@ -84,8 +82,9 @@ public class DataStoreJobCoordinator {
     }
 
     /**
-     * Enqueue a Job with an appropriate key.
-     * A JobEntry is created and queued appropriately.
+     *    This is used by the external applications to enqueue a Job
+     *    with an appropriate key. A JobEntry is created and queued
+     *    appropriately.
      */
     public void enqueueJob(String key, Callable<List<ListenableFuture<Void>>> mainWorker,
                            RollbackCallable rollbackWorker, int maxRetries) {
@@ -102,6 +101,8 @@ public class DataStoreJobCoordinator {
             LOG.trace("Adding jobkey {} to queue {} with size {}", key, hashKey, jobEntriesMap.size());
             jobQueue.addEntry(jobEntry);
             jobEntriesMap.put(key, jobQueue);
+
+            DataStoreJobCoordinatorCounters.jobs_pending.inc();
         }
         reentrantLock.lock();
         try {
@@ -126,10 +127,11 @@ public class DataStoreJobCoordinator {
                 jobEntriesMap.remove(jobEntry.getKey());
             }
         }
+        DataStoreJobCoordinatorCounters.jobs_cleared.inc();
     }
 
     /**
-     * Generate the hashkey for the jobQueueMap.
+     * Used to generate the hashkey in to the jobQueueMap.
      */
     private Integer getHashKey(String key) {
         int code = key.hashCode();
@@ -137,8 +139,8 @@ public class DataStoreJobCoordinator {
     }
 
     /**
-     * JobCallback class is used as a future callback for
-     * main and rollback workers to handle success and failure.
+     * JobCallback class is used as a future callback for main and rollback
+     * workers to handle success and failure.
      */
     private class JobCallback implements FutureCallback<List<Void>> {
         private final JobEntry jobEntry;
@@ -148,7 +150,8 @@ public class DataStoreJobCoordinator {
         }
 
         /**
-         * This implies that all the future instances have returned success. -- TODO: Confirm this
+         * This implies that all the future instances have returned
+         * success. -- TODO: Confirm this
          */
         @Override
         public void onSuccess(List<Void> voids) {
@@ -157,10 +160,11 @@ public class DataStoreJobCoordinator {
         }
 
         /**
-         * Handle failure callbacks.
-         * If more retry needed, the retrycount is decremented and mainworker is executed again.
-         * After retries completed, rollbackworker is executed.
-         * If rollbackworker fails, this is a double-fault. Double fault is logged and ignored.
+         *    This method is used to handle failure callbacks. If more
+         *    retry needed, the retrycount is decremented and mainworker
+         *    is executed again. After retries completed, rollbackworker
+         *    is executed. If rollbackworker fails, this is a
+         *    double-fault. Double fault is logged and ignored.
          */
         @Override
         public void onFailure(Throwable throwable) {
@@ -173,15 +177,12 @@ public class DataStoreJobCoordinator {
             }
 
             int retryCount = jobEntry.decrementRetryCountAndGet();
-            if ( retryCount > 0) {
-                long waitTime = RETRY_WAIT_BASE_TIME * 10 / retryCount;
-                scheduledExecutorService.schedule(
-                    () -> {
-                        MainTask worker = new MainTask(jobEntry);
-                        fjPool.execute(worker);
-                    },
-                    waitTime,
-                    TimeUnit.MILLISECONDS);
+            if (retryCount > 0) {
+                long waitTime = (RETRY_WAIT_BASE_TIME * 10) / retryCount;
+                scheduledExecutorService.schedule(() -> {
+                    MainTask worker = new MainTask(jobEntry);
+                    fjPool.execute(worker);
+                    }, waitTime, TimeUnit.MILLISECONDS);
                 return;
             }
 
@@ -197,7 +198,8 @@ public class DataStoreJobCoordinator {
     }
 
     /**
-     * Execute the RollbackCallable provided by the application in the eventuality of a failure.
+     * RollbackTask is used to execute the RollbackCallable provided by the
+     * application in the eventuality of a failure.
      */
     private class RollbackTask implements Runnable {
         private final JobEntry jobEntry;
@@ -278,8 +280,9 @@ public class DataStoreJobCoordinator {
                         if (jobEntriesMap.isEmpty()) {
                             continue;
                         }
+                        LOG.trace("JobQueueHandler handling queue {} with kesy size {}. Keys: {} ", i,
+                                jobEntriesMap.size(), Arrays.toString(jobEntriesMap.keySet().toArray()));
 
-                        LOG.trace("JobQueueHandler handling queue {} with size {}", i, jobEntriesMap.size());
                         synchronized (jobEntriesMap) {
                             Iterator<Map.Entry<String, JobQueue>> it = jobEntriesMap.entrySet().iterator();
                             while (it.hasNext()) {
@@ -293,8 +296,11 @@ public class DataStoreJobCoordinator {
                                     MainTask worker = new MainTask(jobEntry);
                                     LOG.trace("Executing job {} from queue {}", jobEntry.getKey(), i);
                                     fjPool.execute(worker);
+                                    DataStoreJobCoordinatorCounters.jobs_pending.dec();
+
                                 } else {
                                     it.remove();
+                                    DataStoreJobCoordinatorCounters.jobs_remove_entry.inc();
                                 }
                             }
                         }
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/DataStoreJobCoordinatorCounters.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/DataStoreJobCoordinatorCounters.java
new file mode 100644 (file)
index 0000000..da1768e
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016 Hewlett-Packard Enterprise and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.genius.datastoreutils;
+
+import org.opendaylight.infrautils.counters.api.OccurenceCounter;
+
+public enum DataStoreJobCoordinatorCounters {
+    jobs_remove_entry,
+    jobs_cleared,
+    jobs_pending(true);
+
+    private OccurenceCounter counter;
+
+    DataStoreJobCoordinatorCounters() {
+        counter = new OccurenceCounter(getClass().getSimpleName(), name(), name());
+    }
+
+    DataStoreJobCoordinatorCounters(boolean isState) {
+        counter = new OccurenceCounter(getClass().getSimpleName(), "dsjcc", name(), name(), false, null, true, true);
+    }
+
+    public void inc() {
+        counter.inc();
+    }
+
+    public void dec() {
+        counter.dec();
+    }
+}