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 <orpi...@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")