From bff02155103dbec487096b0adc62243af67712f8 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Tue, 11 Oct 2016 14:59:52 +0200 Subject: [PATCH] [Major] Refactored the DurationExecutionTimer to not be singleton Once again it is clear how bad singletons are. One test killed the timer, thus all other tests failed. Now the DelayedExecutionTimer is retrieved from the ExecutionHandler and is called DelayedExecutionTimer with a default implementation of SimpleDurationExecutionTimer instantiated by the EventBasedExecutionHandler --- .../strolch/rest/StrolchRestfulConstants.java | 1 + .../execution/DelayedExecutionTimer.java | 13 ++++++++++ .../execution/EventBasedExecutionHandler.java | 26 +++++++++++++++++++ .../strolch/execution/ExecutionHandler.java | 2 ++ ...java => SimpleDurationExecutionTimer.java} | 25 +++++++++--------- .../execution/policy/DurationExecution.java | 7 +++-- .../execution/policy/ExecutionPolicy.java | 6 +++++ 7 files changed, 63 insertions(+), 17 deletions(-) create mode 100644 li.strolch.service/src/main/java/li/strolch/execution/DelayedExecutionTimer.java rename li.strolch.service/src/main/java/li/strolch/execution/{DurationExecutionTimer.java => SimpleDurationExecutionTimer.java} (82%) diff --git a/li.strolch.rest/src/main/java/li/strolch/rest/StrolchRestfulConstants.java b/li.strolch.rest/src/main/java/li/strolch/rest/StrolchRestfulConstants.java index 810e542c6..a433fee24 100644 --- a/li.strolch.rest/src/main/java/li/strolch/rest/StrolchRestfulConstants.java +++ b/li.strolch.rest/src/main/java/li/strolch/rest/StrolchRestfulConstants.java @@ -28,6 +28,7 @@ public class StrolchRestfulConstants { public static final String LAST_OFFSET = "lastOffset"; public static final String NEXT_OFFSET = "nextOffset"; public static final String PREVIOUS_OFFSET = "previousOffset"; + public static final String DATA_SET_SIZE = "dataSetSize"; public static final String SIZE = "size"; public static final String OFFSET = "offset"; public static final String LIMIT = "limit"; diff --git a/li.strolch.service/src/main/java/li/strolch/execution/DelayedExecutionTimer.java b/li.strolch.service/src/main/java/li/strolch/execution/DelayedExecutionTimer.java new file mode 100644 index 000000000..fa36313d8 --- /dev/null +++ b/li.strolch.service/src/main/java/li/strolch/execution/DelayedExecutionTimer.java @@ -0,0 +1,13 @@ +package li.strolch.execution; + +import li.strolch.agent.api.ComponentContainer; +import li.strolch.model.Locator; + +public interface DelayedExecutionTimer { + + void cancel(Locator locator); + + void execute(String realm, ComponentContainer container, Locator locator, long duration); + + void destroy(); +} \ No newline at end of file diff --git a/li.strolch.service/src/main/java/li/strolch/execution/EventBasedExecutionHandler.java b/li.strolch.service/src/main/java/li/strolch/execution/EventBasedExecutionHandler.java index 54954ac17..e17d5ac1a 100644 --- a/li.strolch.service/src/main/java/li/strolch/execution/EventBasedExecutionHandler.java +++ b/li.strolch.service/src/main/java/li/strolch/execution/EventBasedExecutionHandler.java @@ -16,10 +16,31 @@ import li.strolch.privilege.model.PrivilegeContext; public class EventBasedExecutionHandler extends ExecutionHandler { + private DelayedExecutionTimer delayedExecutionTimer; + public EventBasedExecutionHandler(ComponentContainer container, String componentName) { super(container, componentName); } + @Override + public void start() throws Exception { + + this.delayedExecutionTimer = new SimpleDurationExecutionTimer(); + + super.start(); + } + + @Override + public void stop() throws Exception { + + if (this.delayedExecutionTimer != null) { + this.delayedExecutionTimer.destroy(); + this.delayedExecutionTimer = null; + } + + super.stop(); + } + @Override public void toExecution(String realm, Locator locator) { runAsAgent(ctx -> { @@ -125,4 +146,9 @@ public class EventBasedExecutionHandler extends ExecutionHandler { protected StrolchTransaction openTx(String realm, Certificate cert, Class clazz) { return getContainer().getRealm(realm).openTx(cert, clazz); } + + @Override + public DelayedExecutionTimer getDelayedExecutionTimer() { + return this.delayedExecutionTimer; + } } diff --git a/li.strolch.service/src/main/java/li/strolch/execution/ExecutionHandler.java b/li.strolch.service/src/main/java/li/strolch/execution/ExecutionHandler.java index f4649b516..5735a4762 100644 --- a/li.strolch.service/src/main/java/li/strolch/execution/ExecutionHandler.java +++ b/li.strolch.service/src/main/java/li/strolch/execution/ExecutionHandler.java @@ -9,6 +9,8 @@ public abstract class ExecutionHandler extends StrolchComponent { public ExecutionHandler(ComponentContainer container, String componentName) { super(container, componentName); } + + public abstract DelayedExecutionTimer getDelayedExecutionTimer(); public abstract void toExecution(String realm, Locator locator); diff --git a/li.strolch.service/src/main/java/li/strolch/execution/DurationExecutionTimer.java b/li.strolch.service/src/main/java/li/strolch/execution/SimpleDurationExecutionTimer.java similarity index 82% rename from li.strolch.service/src/main/java/li/strolch/execution/DurationExecutionTimer.java rename to li.strolch.service/src/main/java/li/strolch/execution/SimpleDurationExecutionTimer.java index 6c90b4f49..6f2cab8e1 100644 --- a/li.strolch.service/src/main/java/li/strolch/execution/DurationExecutionTimer.java +++ b/li.strolch.service/src/main/java/li/strolch/execution/SimpleDurationExecutionTimer.java @@ -11,28 +11,26 @@ import org.slf4j.LoggerFactory; import li.strolch.agent.api.ComponentContainer; import li.strolch.model.Locator; -public class DurationExecutionTimer { +public class SimpleDurationExecutionTimer implements DelayedExecutionTimer { - private static final Logger logger = LoggerFactory.getLogger(DurationExecutionTimer.class); - - private static final DurationExecutionTimer instance; - - static { - instance = new DurationExecutionTimer(); - } - - public static DurationExecutionTimer getInstance() { - return instance; - } + private static final Logger logger = LoggerFactory.getLogger(SimpleDurationExecutionTimer.class); private Timer timer; private Map simulationPolicies; - public DurationExecutionTimer() { + public SimpleDurationExecutionTimer() { this.simulationPolicies = new HashMap<>(); } + @Override + public void destroy() { + if (this.timer != null) { + this.timer.cancel(); + } + } + + @Override public void cancel(Locator locator) { SimulationTask task = this.simulationPolicies.remove(locator); if (task != null) { @@ -40,6 +38,7 @@ public class DurationExecutionTimer { } } + @Override public void execute(String realm, ComponentContainer container, Locator locator, long duration) { if (this.timer == null) this.timer = new Timer("SimulationExecution", true); diff --git a/li.strolch.service/src/main/java/li/strolch/execution/policy/DurationExecution.java b/li.strolch.service/src/main/java/li/strolch/execution/policy/DurationExecution.java index 65cd209d7..48403ba6f 100644 --- a/li.strolch.service/src/main/java/li/strolch/execution/policy/DurationExecution.java +++ b/li.strolch.service/src/main/java/li/strolch/execution/policy/DurationExecution.java @@ -2,7 +2,6 @@ package li.strolch.execution.policy; import li.strolch.agent.api.ComponentContainer; import li.strolch.command.UpdateActivityCommand; -import li.strolch.execution.DurationExecutionTimer; import li.strolch.model.Locator; import li.strolch.model.State; import li.strolch.model.activity.Action; @@ -33,7 +32,7 @@ public class DurationExecution extends ExecutionPolicy { String realmName = tx().getRealmName(); Locator locator = action.getLocator(); logger.warn("Executing action " + action.getLocator() + " has a duration of " + durationP.getValueAsString()); - DurationExecutionTimer.getInstance().execute(realmName, getContainer(), locator, durationP.getValue()); + getDelayedExecutionTimer().execute(realmName, getContainer(), locator, durationP.getValue()); action.setState(State.EXECUTION); @@ -59,7 +58,7 @@ public class DurationExecution extends ExecutionPolicy { @Override public void toStopped(Action action) { - DurationExecutionTimer.getInstance().cancel(action.getLocator()); + getDelayedExecutionTimer().cancel(action.getLocator()); action.setState(State.STOPPED); @@ -73,7 +72,7 @@ public class DurationExecution extends ExecutionPolicy { @Override public void toError(Action action) { - DurationExecutionTimer.getInstance().cancel(action.getLocator()); + getDelayedExecutionTimer().cancel(action.getLocator()); action.setState(State.ERROR); 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 4959c5873..4f4f0cd5c 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 @@ -2,6 +2,8 @@ package li.strolch.execution.policy; import li.strolch.agent.api.ComponentContainer; import li.strolch.command.UpdateActivityCommand; +import li.strolch.execution.DelayedExecutionTimer; +import li.strolch.execution.ExecutionHandler; import li.strolch.model.State; import li.strolch.model.activity.Action; import li.strolch.persistence.api.StrolchTransaction; @@ -31,4 +33,8 @@ public abstract class ExecutionPolicy extends StrolchPolicy { logger.warn("Action " + action.getLocator() + " is now in WARNING!"); } + + protected DelayedExecutionTimer getDelayedExecutionTimer() { + return getComponent(ExecutionHandler.class).getDelayedExecutionTimer(); + } }