[New] Allow to retry execution on locking exception in ExecutionHandler
Default is trying twice: executionHandler.getConfiguration().getInt(PROP_LOCK_RETRIES, 2)
This commit is contained in:
parent
668181e46b
commit
9631d80ca2
|
@ -1,6 +1,7 @@
|
||||||
package li.strolch.execution;
|
package li.strolch.execution;
|
||||||
|
|
||||||
import static java.util.Collections.synchronizedMap;
|
import static java.util.Collections.synchronizedMap;
|
||||||
|
import static li.strolch.execution.EventBasedExecutionHandler.PROP_LOCK_RETRIES;
|
||||||
import static li.strolch.runtime.StrolchConstants.SYSTEM_USER_AGENT;
|
import static li.strolch.runtime.StrolchConstants.SYSTEM_USER_AGENT;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -9,6 +10,7 @@ import java.util.ResourceBundle;
|
||||||
|
|
||||||
import li.strolch.agent.api.ComponentContainer;
|
import li.strolch.agent.api.ComponentContainer;
|
||||||
import li.strolch.agent.api.ObserverEvent;
|
import li.strolch.agent.api.ObserverEvent;
|
||||||
|
import li.strolch.agent.api.StrolchLockException;
|
||||||
import li.strolch.agent.api.StrolchRealm;
|
import li.strolch.agent.api.StrolchRealm;
|
||||||
import li.strolch.execution.command.*;
|
import li.strolch.execution.command.*;
|
||||||
import li.strolch.execution.policy.ExecutionPolicy;
|
import li.strolch.execution.policy.ExecutionPolicy;
|
||||||
|
@ -32,6 +34,7 @@ public class Controller {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(Controller.class);
|
private static final Logger logger = LoggerFactory.getLogger(Controller.class);
|
||||||
|
|
||||||
|
private final int lockRetries;
|
||||||
private final String realm;
|
private final String realm;
|
||||||
private final ComponentContainer container;
|
private final ComponentContainer container;
|
||||||
private final ExecutionHandler executionHandler;
|
private final ExecutionHandler executionHandler;
|
||||||
|
@ -53,6 +56,7 @@ public class Controller {
|
||||||
this.activityId = activity.getId();
|
this.activityId = activity.getId();
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
this.inExecution = synchronizedMap(new HashMap<>());
|
this.inExecution = synchronizedMap(new HashMap<>());
|
||||||
|
this.lockRetries = executionHandler.getConfiguration().getInt(PROP_LOCK_RETRIES, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRealm() {
|
public String getRealm() {
|
||||||
|
@ -115,7 +119,7 @@ public class Controller {
|
||||||
boolean[] trigger = new boolean[1];
|
boolean[] trigger = new boolean[1];
|
||||||
this.executionHandler.runAsAgent(ctx -> {
|
this.executionHandler.runAsAgent(ctx -> {
|
||||||
try (StrolchTransaction tx = openTx(ctx.getCertificate())) {
|
try (StrolchTransaction tx = openTx(ctx.getCertificate())) {
|
||||||
tx.lock(this.locator);
|
lockWithRetries(tx);
|
||||||
trigger[0] = execute(tx);
|
trigger[0] = execute(tx);
|
||||||
if (tx.needsCommit()) {
|
if (tx.needsCommit()) {
|
||||||
tx.commitOnClose();
|
tx.commitOnClose();
|
||||||
|
@ -173,7 +177,7 @@ public class Controller {
|
||||||
public void toExecuted(Locator actionLoc) throws Exception {
|
public void toExecuted(Locator actionLoc) throws Exception {
|
||||||
this.executionHandler.runAsAgent(ctx -> {
|
this.executionHandler.runAsAgent(ctx -> {
|
||||||
try (StrolchTransaction tx = openTx(ctx.getCertificate())) {
|
try (StrolchTransaction tx = openTx(ctx.getCertificate())) {
|
||||||
tx.lock(this.locator);
|
lockWithRetries(tx);
|
||||||
|
|
||||||
if (!refreshActivity(tx))
|
if (!refreshActivity(tx))
|
||||||
return;
|
return;
|
||||||
|
@ -212,7 +216,7 @@ public class Controller {
|
||||||
public void toStopped(Locator actionLoc) throws Exception {
|
public void toStopped(Locator actionLoc) throws Exception {
|
||||||
this.executionHandler.runAsAgent(ctx -> {
|
this.executionHandler.runAsAgent(ctx -> {
|
||||||
try (StrolchTransaction tx = openTx(ctx.getCertificate())) {
|
try (StrolchTransaction tx = openTx(ctx.getCertificate())) {
|
||||||
tx.lock(this.locator);
|
lockWithRetries(tx);
|
||||||
|
|
||||||
if (!refreshActivity(tx))
|
if (!refreshActivity(tx))
|
||||||
return;
|
return;
|
||||||
|
@ -242,7 +246,7 @@ public class Controller {
|
||||||
public void toError(Locator actionLoc) throws Exception {
|
public void toError(Locator actionLoc) throws Exception {
|
||||||
this.executionHandler.runAsAgent(ctx -> {
|
this.executionHandler.runAsAgent(ctx -> {
|
||||||
try (StrolchTransaction tx = openTx(ctx.getCertificate())) {
|
try (StrolchTransaction tx = openTx(ctx.getCertificate())) {
|
||||||
tx.lock(this.locator);
|
lockWithRetries(tx);
|
||||||
|
|
||||||
if (!refreshActivity(tx))
|
if (!refreshActivity(tx))
|
||||||
return;
|
return;
|
||||||
|
@ -272,7 +276,7 @@ public class Controller {
|
||||||
public void toWarning(Locator actionLoc) throws Exception {
|
public void toWarning(Locator actionLoc) throws Exception {
|
||||||
this.executionHandler.runAsAgent(ctx -> {
|
this.executionHandler.runAsAgent(ctx -> {
|
||||||
try (StrolchTransaction tx = openTx(ctx.getCertificate())) {
|
try (StrolchTransaction tx = openTx(ctx.getCertificate())) {
|
||||||
tx.lock(this.locator);
|
lockWithRetries(tx);
|
||||||
|
|
||||||
if (!refreshActivity(tx))
|
if (!refreshActivity(tx))
|
||||||
return;
|
return;
|
||||||
|
@ -339,6 +343,29 @@ public class Controller {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void lockWithRetries(StrolchTransaction tx) throws StrolchLockException {
|
||||||
|
int tries = 0;
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
tx.lock(this.locator);
|
||||||
|
return;
|
||||||
|
|
||||||
|
} catch (StrolchLockException e) {
|
||||||
|
tries++;
|
||||||
|
if (tries >= this.lockRetries) {
|
||||||
|
logger.error("Failed to lock " + this.locator + ". Max retries " + tries
|
||||||
|
+ " reached, throwing exception!");
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.error("LOCK FAILURE!");
|
||||||
|
logger.error("Failed to lock " + this.locator + ". Trying again...");
|
||||||
|
logger.error("LOCK FAILURE!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateObservers() {
|
private void updateObservers() {
|
||||||
StrolchRealm realm = this.executionHandler.getContainer().getRealm(this.realm);
|
StrolchRealm realm = this.executionHandler.getContainer().getRealm(this.realm);
|
||||||
if (!realm.isUpdateObservers())
|
if (!realm.isUpdateObservers())
|
||||||
|
|
|
@ -34,8 +34,6 @@ import li.strolch.utils.collections.MapOfMaps;
|
||||||
*/
|
*/
|
||||||
public class EventBasedExecutionHandler extends ExecutionHandler {
|
public class EventBasedExecutionHandler extends ExecutionHandler {
|
||||||
|
|
||||||
private static final String PROP_RESTART_EXECUTION = "restartExecution";
|
|
||||||
|
|
||||||
private Map<String, ExecutionHandlerState> statesByRealm;
|
private Map<String, ExecutionHandlerState> statesByRealm;
|
||||||
private MapOfMaps<String, Locator, Controller> controllers;
|
private MapOfMaps<String, Locator, Controller> controllers;
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,9 @@ public abstract class ExecutionHandler extends StrolchComponent {
|
||||||
super(container, componentName);
|
super(container, componentName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final String PROP_RESTART_EXECUTION = "restartExecution";
|
||||||
|
public static final String PROP_LOCK_RETRIES = "lockRetries";
|
||||||
|
|
||||||
public static final String PARAM_STATE = "state";
|
public static final String PARAM_STATE = "state";
|
||||||
|
|
||||||
public StrolchTransaction openTx(String realm, Certificate cert, Class<?> action, boolean readOnly) {
|
public StrolchTransaction openTx(String realm, Certificate cert, Class<?> action, boolean readOnly) {
|
||||||
|
|
Loading…
Reference in New Issue