diff --git a/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java b/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java index 365a222f5dafd4d5ff4f52177bd1bb458316cc3e..8dc919c89269ef46602a71be7a4b5ec2296c82ad 100644 --- a/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java +++ b/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java @@ -36,6 +36,11 @@ import net.floodlightcontroller.counter.CounterStore; import net.floodlightcontroller.counter.ICounter; import net.floodlightcontroller.counter.ICounterStoreService; import net.floodlightcontroller.counter.SimpleCounter; +import net.floodlightcontroller.debugcounter.IDebugCounter; +import net.floodlightcontroller.debugcounter.IDebugCounterService; +import net.floodlightcontroller.debugcounter.NullDebugCounter; +import net.floodlightcontroller.debugcounter.IDebugCounterService.CounterException; +import net.floodlightcontroller.debugcounter.IDebugCounterService.CounterType; import net.floodlightcontroller.flowcache.IFlowReconcileListener; import net.floodlightcontroller.flowcache.OFMatchReconcile; import net.floodlightcontroller.flowcache.PriorityPendingQueue.EventPriority; @@ -55,7 +60,7 @@ public class FlowReconcileManager /** Reference to dependent modules */ protected IThreadPoolService threadPool; protected ICounterStoreService counterStore; - + protected IDebugCounterService debugCounters; /** * The list of flow reconcile listeners that have registered to get * flow reconcile callbacks. Such callbacks are invoked, for example, when @@ -85,6 +90,13 @@ public class FlowReconcileManager /** Config to enable or disable flowReconcile */ protected static final String EnableConfigKey = "enable"; + + /* + * Debug Counters + */ + public static final String PACKAGE = FlowReconcileManager.class.getPackage().getName(); + private IDebugCounter ctrFlowReconcileRequest; + private IDebugCounter ctrReconciledFlows; protected boolean flowReconcileEnabled; public AtomicInteger flowReconcileThreadRunCount; @@ -130,6 +142,7 @@ public class FlowReconcileManager OFMatchReconcile myOfmRc = new OFMatchReconcile(ofmRcIn); flowQueue.offer(myOfmRc, priority); + ctrFlowReconcileRequest.updateCounterWithFlush(); Date currTime = new Date(); long delay = 0; @@ -187,7 +200,7 @@ public class FlowReconcileManager throws FloodlightModuleException { threadPool = context.getServiceImpl(IThreadPoolService.class); counterStore = context.getServiceImpl(ICounterStoreService.class); - + debugCounters = context.getServiceImpl(IDebugCounterService.class); flowQueue = new PriorityPendingQueue<OFMatchReconcile>(); flowReconcileListeners = new ListenerDispatcher<OFType, IFlowReconcileListener>(); @@ -200,12 +213,30 @@ public class FlowReconcileManager enableValue.equalsIgnoreCase("false")) { flowReconcileEnabled = false; } - + registerFlowReconcileManagerDebugCounters(); flowReconcileThreadRunCount = new AtomicInteger(0); lastReconcileTime = new Date(0); logger.debug("FlowReconcile is {}", flowReconcileEnabled); } + private void registerFlowReconcileManagerDebugCounters() throws FloodlightModuleException { + if (debugCounters == null) { + logger.error("Debug Counter Service not found."); + debugCounters = new NullDebugCounter(); + } + try { + ctrFlowReconcileRequest = debugCounters.registerCounter(PACKAGE, "flow-reconcile-request", + "All flow reconcile request received by this module", + CounterType.ALWAYS_COUNT); + ctrReconciledFlows = debugCounters.registerCounter(PACKAGE, "reconciled-flows", + "All flows reconciled successfully by this module", + CounterType.ALWAYS_COUNT); + } catch (CounterException e) { + throw new FloodlightModuleException(e.getMessage()); + } + } + + @Override public void startUp(FloodlightModuleContext context) { // thread to do flow reconcile @@ -264,6 +295,7 @@ public class FlowReconcileManager reconcileCapacity--; if (ofmRc != null) { ofmRcList.add(ofmRc); + ctrReconciledFlows.updateCounterWithFlush(); if (logger.isTraceEnabled()) { logger.trace("Add flow {} to be the reconcileList", ofmRc.cookie); } diff --git a/src/main/java/net/floodlightcontroller/flowcache/PriorityPendingQueue.java b/src/main/java/net/floodlightcontroller/flowcache/PriorityPendingQueue.java index c56510c242c415d7577ed53e6a8b5326655f8d76..5f90a24e50ac429ebe3f4713b68807589865a32e 100644 --- a/src/main/java/net/floodlightcontroller/flowcache/PriorityPendingQueue.java +++ b/src/main/java/net/floodlightcontroller/flowcache/PriorityPendingQueue.java @@ -1,11 +1,10 @@ package net.floodlightcontroller.flowcache; -import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; - /** * PriorityPendingQueue class - This class is a variant implementation for PriorityBlockingQueue * PriorityBlockingQueue implementation has two problems: @@ -25,9 +24,9 @@ import java.util.concurrent.locks.ReentrantLock; * */ public class PriorityPendingQueue<E> { - private ArrayBlockingQueue<E> highPriorityQueue; - private ArrayBlockingQueue<E> mediumPriorityQueue; - private ArrayBlockingQueue<E> lowPriorityQueue; + private LinkedBlockingQueue<E> highPriorityQueue; + private LinkedBlockingQueue<E> mediumPriorityQueue; + private LinkedBlockingQueue<E> lowPriorityQueue; private final AtomicInteger count = new AtomicInteger(0); private final ReentrantLock takeLock = new ReentrantLock(); private final Condition notEmpty = takeLock.newCondition(); @@ -40,9 +39,9 @@ public class PriorityPendingQueue<E> { LOW, } public PriorityPendingQueue() { - highPriorityQueue= new ArrayBlockingQueue<E>(1000); - mediumPriorityQueue= new ArrayBlockingQueue<E>(1000); - lowPriorityQueue= new ArrayBlockingQueue<E>(5000); + highPriorityQueue= new LinkedBlockingQueue<E>(); + mediumPriorityQueue= new LinkedBlockingQueue<E>(); + lowPriorityQueue= new LinkedBlockingQueue<E>(); capacity= Integer.MAX_VALUE; }