BUG-5280: add FrontendMetadata
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / TransactionRateLimitingCallback.java
index 678891446ab9b3da8c87315497bb1f044b681897..8ba2cb9ad936d8636c0b60bf6e40db0493d842d0 100644 (file)
@@ -9,7 +9,10 @@
 package org.opendaylight.controller.cluster.datastore;
 
 import com.codahale.metrics.Timer;
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
+import com.google.common.base.Ticker;
+import java.util.concurrent.TimeUnit;
 import org.opendaylight.controller.cluster.datastore.utils.ActorContext;
 
 /**
@@ -17,8 +20,18 @@ import org.opendaylight.controller.cluster.datastore.utils.ActorContext;
  * transaction
  */
 public class TransactionRateLimitingCallback implements OperationCallback{
+    private static Ticker TICKER = Ticker.systemTicker();
+
+    private static enum State {
+        STOPPED,
+        RUNNING,
+        PAUSED
+    }
+
     private final Timer commitTimer;
-    private Timer.Context timerContext;
+    private long startTime;
+    private long elapsedTime;
+    private volatile State state = State.STOPPED;
 
     TransactionRateLimitingCallback(ActorContext actorContext){
         commitTimer = actorContext.getOperationTimer(ActorContext.COMMIT);
@@ -26,13 +39,32 @@ public class TransactionRateLimitingCallback implements OperationCallback{
 
     @Override
     public void run() {
-        timerContext = commitTimer.time();
+        Preconditions.checkState(state == State.STOPPED, "state is not STOPPED");
+        resume();
+    }
+
+    @Override
+    public void pause() {
+        if(state == State.RUNNING) {
+            elapsedTime += TICKER.read() - startTime;
+            state = State.PAUSED;
+        }
+    }
+
+    @Override
+    public void resume() {
+        if(state != State.RUNNING) {
+            startTime = TICKER.read();
+            state = State.RUNNING;
+        }
     }
 
     @Override
     public void success() {
-        Preconditions.checkState(timerContext != null, "Call run before success");
-        timerContext.stop();
+        Preconditions.checkState(state != State.STOPPED, "state is STOPPED");
+        pause();
+        commitTimer.update(elapsedTime, TimeUnit.NANOSECONDS);
+        state = State.STOPPED;
     }
 
     @Override
@@ -42,4 +74,8 @@ public class TransactionRateLimitingCallback implements OperationCallback{
         // not going to be useful - so we leave it as it is
     }
 
+    @VisibleForTesting
+    static void setTicker(Ticker ticker) {
+        TICKER = ticker;
+    }
 }
\ No newline at end of file