You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2021/11/11 19:27:09 UTC

[camel] branch main updated: CAMEL-17121: added support for accounting and reporting the elapsed time (#6425)

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new b4245f5  CAMEL-17121: added support for accounting and reporting the elapsed time (#6425)
b4245f5 is described below

commit b4245f5df33359e6c992b55e423c8564a5c44b01
Author: Otavio Rodolfo Piske <or...@users.noreply.github.com>
AuthorDate: Thu Nov 11 20:26:07 2021 +0100

    CAMEL-17121: added support for accounting and reporting the elapsed time (#6425)
    
    * CAMEL-17121: added support for accounting and reporting the elapsed time for a task
    
    * CAMEL-17121: adjust the producer cache log to use the tasks elapsed counter
---
 .../org/apache/camel/support/cache/DefaultProducerCache.java |  3 +--
 .../java/org/apache/camel/support/task/BackgroundTask.java   |  6 ++++++
 .../java/org/apache/camel/support/task/ForegroundTask.java   |  6 ++++++
 .../src/main/java/org/apache/camel/support/task/Task.java    |  9 +++++++++
 .../java/org/apache/camel/support/task/budget/Budget.java    | 12 ++++++++++++
 .../camel/support/task/budget/IterationBoundedBudget.java    | 11 +++++++++++
 .../support/task/budget/IterationTimeBoundedBudget.java      |  6 ++++++
 .../apache/camel/support/task/budget/TimeBoundedBudget.java  |  7 ++++++-
 .../org/apache/camel/support/task/BackgroundTaskTest.java    | 11 +++++++++--
 .../org/apache/camel/support/task/ForegroundTaskTest.java    |  8 ++++++++
 .../apache/camel/support/task/ForegroundTimeTaskTest.java    |  8 ++++++++
 11 files changed, 82 insertions(+), 5 deletions(-)

diff --git a/core/camel-support/src/main/java/org/apache/camel/support/cache/DefaultProducerCache.java b/core/camel-support/src/main/java/org/apache/camel/support/cache/DefaultProducerCache.java
index 97152e4..9854f62 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/cache/DefaultProducerCache.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/cache/DefaultProducerCache.java
@@ -133,13 +133,12 @@ public class DefaultProducerCache extends ServiceSupport implements ProducerCach
                 .build())
                 .build();
 
-        StopWatch watch = LOG.isDebugEnabled() ? new StopWatch() : null;
         if (!task.run(service::isStarting)) {
             LOG.warn("The producer: {} did not finish starting in {} ms", service, ACQUIRE_WAIT_TIME);
         }
 
         if (LOG.isDebugEnabled()) {
-            LOG.debug("Waited {} ms for producer to finish starting: {} state: {}", watch.taken(), service,
+            LOG.debug("Waited {} ms for producer to finish starting: {} state: {}", task.elapsed().toMillis(), service,
                     service.getStatus());
         }
     }
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/task/BackgroundTask.java b/core/camel-support/src/main/java/org/apache/camel/support/task/BackgroundTask.java
index 48567b1..fc3e60c 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/task/BackgroundTask.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/task/BackgroundTask.java
@@ -17,6 +17,7 @@
 
 package org.apache.camel.support.task;
 
+import java.time.Duration;
 import java.util.Objects;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ScheduledExecutorService;
@@ -172,4 +173,9 @@ public class BackgroundTask implements BlockingTask {
 
         return completed;
     }
+
+    @Override
+    public Duration elapsed() {
+        return budget.elapsed();
+    }
 }
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/task/ForegroundTask.java b/core/camel-support/src/main/java/org/apache/camel/support/task/ForegroundTask.java
index d5f798f..a77de9b 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/task/ForegroundTask.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/task/ForegroundTask.java
@@ -17,6 +17,7 @@
 
 package org.apache.camel.support.task;
 
+import java.time.Duration;
 import java.util.Optional;
 import java.util.function.BooleanSupplier;
 import java.util.function.Predicate;
@@ -156,4 +157,9 @@ public class ForegroundTask implements BlockingTask {
 
         return Optional.empty();
     }
+
+    @Override
+    public Duration elapsed() {
+        return budget.elapsed();
+    }
 }
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/task/Task.java b/core/camel-support/src/main/java/org/apache/camel/support/task/Task.java
index e6771b3..e0dce77 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/task/Task.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/task/Task.java
@@ -17,9 +17,18 @@
 
 package org.apache.camel.support.task;
 
+import java.time.Duration;
+
 /**
  * A task defines a piece of code that may be executed - in the foreground or background - within a certain budget that
  * is specific to the task type.
  */
 public interface Task {
+
+    /**
+     * How long it took to run the task
+     * 
+     * @return The duration to execute the task
+     */
+    Duration elapsed();
 }
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/task/budget/Budget.java b/core/camel-support/src/main/java/org/apache/camel/support/task/budget/Budget.java
index b4ea140..9fd912b 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/task/budget/Budget.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/task/budget/Budget.java
@@ -17,6 +17,8 @@
 
 package org.apache.camel.support.task.budget;
 
+import java.time.Duration;
+
 /**
  * A budget defines how much a task can execute
  */
@@ -48,4 +50,14 @@ public interface Budget {
      * @return true if the task can continue or false otherwise
      */
     boolean next();
+
+    /**
+     * The amount of time that has elapsed since the budget was created. This can be used to account for the amount of
+     * time it took to run a task. The precision should be withing a few microseconds/milliseconds due to the start time
+     * being created along with the budget instance. We do so to avoid the overhead of checking it the next or
+     * canContinue methods because they could be part of the hot path for some components.
+     * 
+     * @return The amount of time that has elapsed since the budget was created
+     */
+    Duration elapsed();
 }
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/task/budget/IterationBoundedBudget.java b/core/camel-support/src/main/java/org/apache/camel/support/task/budget/IterationBoundedBudget.java
index 4ee42db..ce92279 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/task/budget/IterationBoundedBudget.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/task/budget/IterationBoundedBudget.java
@@ -17,6 +17,9 @@
 
 package org.apache.camel.support.task.budget;
 
+import java.time.Duration;
+import java.time.Instant;
+
 import org.apache.camel.support.task.budget.backoff.BackOffStrategy;
 import org.apache.camel.support.task.budget.backoff.FixedBackOffStrategy;
 
@@ -32,18 +35,21 @@ public class IterationBoundedBudget implements IterationBudget {
     private final long initialDelay;
     private final int maxIterations;
     private final BackOffStrategy backOffStrategy;
+    private final Instant startTime;
     private int iterations;
 
     IterationBoundedBudget(long initialDelay, long interval, int maxIterations) {
         this.initialDelay = initialDelay;
         this.maxIterations = maxIterations;
         this.backOffStrategy = new FixedBackOffStrategy(interval);
+        this.startTime = Instant.now();
     }
 
     IterationBoundedBudget(long initialDelay, int maxIterations, BackOffStrategy backOffStrategy) {
         this.initialDelay = initialDelay;
         this.maxIterations = maxIterations;
         this.backOffStrategy = backOffStrategy;
+        this.startTime = Instant.now();
     }
 
     @Override
@@ -86,4 +92,9 @@ public class IterationBoundedBudget implements IterationBudget {
 
         return true;
     }
+
+    @Override
+    public Duration elapsed() {
+        return Duration.between(startTime, Instant.now());
+    }
 }
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/task/budget/IterationTimeBoundedBudget.java b/core/camel-support/src/main/java/org/apache/camel/support/task/budget/IterationTimeBoundedBudget.java
index 30de527..78d60d3 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/task/budget/IterationTimeBoundedBudget.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/task/budget/IterationTimeBoundedBudget.java
@@ -17,6 +17,8 @@
 
 package org.apache.camel.support.task.budget;
 
+import java.time.Duration;
+
 /**
  * This task budget limits the execution by both a given number of iterations or a maximum amount of time for the
  * execution. When evaluating the budget, the iteration takes precedence over the time budget (hence why: Iteration Time
@@ -79,4 +81,8 @@ public class IterationTimeBoundedBudget implements IterationBudget, TimeBudget {
         return timeBoundedBudget.maxDuration();
     }
 
+    @Override
+    public Duration elapsed() {
+        return timeBoundedBudget.elapsed();
+    }
 }
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/task/budget/TimeBoundedBudget.java b/core/camel-support/src/main/java/org/apache/camel/support/task/budget/TimeBoundedBudget.java
index 493d412..1c57329 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/task/budget/TimeBoundedBudget.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/task/budget/TimeBoundedBudget.java
@@ -56,7 +56,7 @@ public class TimeBoundedBudget implements TimeBudget {
     @Override
     public boolean canContinue() {
         // ... if time budget is NOT exhausted
-        if (Duration.between(startTime, Instant.now()).toMillis() >= maxDuration) {
+        if (elapsed().toMillis() >= maxDuration) {
             return false;
         }
 
@@ -67,4 +67,9 @@ public class TimeBoundedBudget implements TimeBudget {
     public boolean next() {
         return true;
     }
+
+    @Override
+    public Duration elapsed() {
+        return Duration.between(startTime, Instant.now());
+    }
 }
diff --git a/core/camel-support/src/test/java/org/apache/camel/support/task/BackgroundTaskTest.java b/core/camel-support/src/test/java/org/apache/camel/support/task/BackgroundTaskTest.java
index c5a4bb9..3d283c6 100644
--- a/core/camel-support/src/test/java/org/apache/camel/support/task/BackgroundTaskTest.java
+++ b/core/camel-support/src/test/java/org/apache/camel/support/task/BackgroundTaskTest.java
@@ -27,11 +27,12 @@ import org.junit.jupiter.api.Timeout;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class BackgroundTaskTest extends TaskTestSupport {
 
-    @DisplayName("Test that the task does not run for more than the max iterations when using a supplier")
+    @DisplayName("Test that the task does not run for more than the max iterations when using a supplier with no delay")
     @Test
     @Timeout(10)
     void testRunNoMoreSupplier() {
@@ -48,9 +49,15 @@ public class BackgroundTaskTest extends TaskTestSupport {
         boolean completed = task.run(this::booleanSupplier);
         assertEquals(maxIterations, taskCount);
         assertFalse(completed, "The task did not complete, the return should be false");
+
+        Duration duration = task.elapsed();
+        assertNotNull(duration);
+        assertFalse(duration.isNegative());
+        assertFalse(duration.isZero());
+        assertTrue(duration.toMillis() > 0);
     }
 
-    @DisplayName("Test that the task does not run for more than the max iterations when using a supplier")
+    @DisplayName("Test that the task does not run for more than the max iterations when using a supplier with delay")
     @Test
     @Timeout(10)
     void testRunNoMoreSupplierWithDelay() {
diff --git a/core/camel-support/src/test/java/org/apache/camel/support/task/ForegroundTaskTest.java b/core/camel-support/src/test/java/org/apache/camel/support/task/ForegroundTaskTest.java
index 7b69371..83b9f54 100644
--- a/core/camel-support/src/test/java/org/apache/camel/support/task/ForegroundTaskTest.java
+++ b/core/camel-support/src/test/java/org/apache/camel/support/task/ForegroundTaskTest.java
@@ -25,6 +25,8 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Timeout;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class ForegroundTaskTest extends TaskTestSupport {
@@ -44,6 +46,12 @@ public class ForegroundTaskTest extends TaskTestSupport {
 
         task.run(this::booleanSupplier);
         assertEquals(maxIterations, taskCount);
+
+        Duration duration = task.elapsed();
+        assertNotNull(duration);
+        assertFalse(duration.isNegative());
+        assertFalse(duration.isZero());
+        assertTrue(duration.toMillis() > 0);
     }
 
     @DisplayName("Test that the task does not run for more than the max iterations when using a supplier")
diff --git a/core/camel-support/src/test/java/org/apache/camel/support/task/ForegroundTimeTaskTest.java b/core/camel-support/src/test/java/org/apache/camel/support/task/ForegroundTimeTaskTest.java
index a8b0139..292891c 100644
--- a/core/camel-support/src/test/java/org/apache/camel/support/task/ForegroundTimeTaskTest.java
+++ b/core/camel-support/src/test/java/org/apache/camel/support/task/ForegroundTimeTaskTest.java
@@ -25,6 +25,8 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Timeout;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class ForegroundTimeTaskTest extends TaskTestSupport {
@@ -45,6 +47,12 @@ public class ForegroundTimeTaskTest extends TaskTestSupport {
 
         task.run(this::booleanSupplier);
         assertEquals(maxIterations, taskCount);
+
+        Duration duration = task.elapsed();
+        assertNotNull(duration);
+        assertFalse(duration.isNegative());
+        assertFalse(duration.isZero());
+        assertTrue(duration.toMillis() > 0);
     }
 
     @DisplayName("Test that the task does not run for more than the max iterations when using a supplier and an initial delay")