From eebdc963f379f16d31f503a1fbdd73b0190b1f1a Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Thu, 20 Feb 2020 18:00:15 +0100 Subject: [PATCH] [New] Added ExecutionPolicy.delayToExecutedBy() and delayToExecutedByRandom() --- .../execution/policy/ExecutionPolicy.java | 57 ++++++++++++++++++- .../policy/RandomDurationExecution.java | 34 +++++++++++ 2 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 li.strolch.service/src/main/java/li/strolch/execution/policy/RandomDurationExecution.java diff --git a/li.strolch.service/src/main/java/li/strolch/execution/policy/ExecutionPolicy.java b/li.strolch.service/src/main/java/li/strolch/execution/policy/ExecutionPolicy.java index 294666182..aae9c41f5 100644 --- a/li.strolch.service/src/main/java/li/strolch/execution/policy/ExecutionPolicy.java +++ b/li.strolch.service/src/main/java/li/strolch/execution/policy/ExecutionPolicy.java @@ -1,5 +1,11 @@ package li.strolch.execution.policy; +import static li.strolch.utils.helper.StringHelper.formatMillisecondsDuration; + +import java.time.Duration; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; + import li.strolch.agent.api.ComponentContainer; import li.strolch.agent.api.StrolchRealm; import li.strolch.exception.StrolchException; @@ -165,7 +171,9 @@ public abstract class ExecutionPolicy extends StrolchPolicy { } } - protected abstract void handleStopped(); + protected void handleStopped() { + getDelayedExecutionTimer().cancel(this.actionLoc); + } protected void setActionState(Action action, State state) { @@ -182,11 +190,56 @@ public abstract class ExecutionPolicy extends StrolchPolicy { logger.info(msg); } + /** + * Method to delay toExecuted() call for this action by the given duration + * + * @param duration + * the delay duration + */ + protected void delayToExecutedBy(Duration duration) { + String realmName = tx().getRealmName(); + long delayMs = duration.toMillis(); + if (delayMs < 20) { + logger.warn("Delay time for " + this.actionLoc + " is less than 20ms, overriding!"); + delayMs = 20; + } + logger.info("Delaying toExecuted of " + this.actionLoc + " by " + formatMillisecondsDuration(delayMs)); + getDelayedExecutionTimer().execute(realmName, getContainer(), this.actionLoc, delayMs); + } + + protected void delayToExecutedByRandom(long duration, double minFactor, double maxFactor, TimeUnit delayUnit) { + delayToExecutedByRandom((long) (duration * minFactor), (long) (duration * maxFactor), delayUnit); + } + + protected void delayToExecutedByRandom(long min, long max, TimeUnit delayUnit) { + long delay = ThreadLocalRandom.current().nextLong(min, max + 1); + delayToExecutedBy(delay, delayUnit); + } + + /** + * Method to delay toExecuted() call for this action by the given amount + * + * @param delay + * the delay time + * @param delayUnit + * the UOM of the delay time + */ + protected void delayToExecutedBy(long delay, TimeUnit delayUnit) { + String realmName = tx().getRealmName(); + long delayMs = delayUnit.toMillis(delay); + if (delayMs < 20) { + logger.warn("Delay time for " + this.actionLoc + " is less than 20ms, overriding!"); + delayMs = 20; + } + logger.info("Delaying toExecuted of " + this.actionLoc + " by " + formatMillisecondsDuration(delayMs)); + getDelayedExecutionTimer().execute(realmName, getContainer(), this.actionLoc, delayMs); + } + /** * @return the {@link DelayedExecutionTimer} to simplify the delayed execution of an {@link Action}, e.g. for * simulated execution or simple wait tasks */ - protected DelayedExecutionTimer getDelayedExecutionTimer() { + private DelayedExecutionTimer getDelayedExecutionTimer() { return getComponent(ExecutionHandler.class).getDelayedExecutionTimer(); } diff --git a/li.strolch.service/src/main/java/li/strolch/execution/policy/RandomDurationExecution.java b/li.strolch.service/src/main/java/li/strolch/execution/policy/RandomDurationExecution.java new file mode 100644 index 000000000..b977a9936 --- /dev/null +++ b/li.strolch.service/src/main/java/li/strolch/execution/policy/RandomDurationExecution.java @@ -0,0 +1,34 @@ +package li.strolch.execution.policy; + +import static li.strolch.runtime.StrolchConstants.PolicyConstants.BAG_OBJECTIVES; +import static li.strolch.runtime.StrolchConstants.PolicyConstants.PARAM_DURATION; + +import java.util.concurrent.TimeUnit; + +import li.strolch.model.activity.Action; +import li.strolch.model.parameter.DurationParameter; +import li.strolch.persistence.api.StrolchTransaction; + +/** + *

+ * Simple Execution Policy which starts the execution immediately, i.e. set state to in execution and completes after + * the {@link Action Action's} duration has passed. + *

+ * + * @author Robert von Burg + */ +public class RandomDurationExecution extends SimpleExecution { + + public RandomDurationExecution(StrolchTransaction tx) { + super(tx); + } + + @Override + public void toExecution(Action action) { + + DurationParameter durationP = action.findParameter(BAG_OBJECTIVES, PARAM_DURATION, true); + delayToExecutedByRandom(durationP.toMillis(), 0.5, 2, TimeUnit.MILLISECONDS); + + super.toExecution(action); + } +}