[Fix] lock action's resource early by locator to stop race condition
This commit is contained in:
parent
cf9739f091
commit
c8d23d0393
|
@ -26,6 +26,9 @@ public class ExecuteStoppedActionCommand extends ExecutionCommand {
|
|||
public void validate() {
|
||||
DBC.PRE.assertNotNull("action can not be null", this.action);
|
||||
|
||||
tx().lock(this.action.getRootElement());
|
||||
tx().lock(getResourceLocator(this.action));
|
||||
|
||||
if (this.action.getState() != State.STOPPED) {
|
||||
String msg = "Action {0} is not in state " + State.STOPPED + " and can thus not be put into execution!";
|
||||
msg = MessageFormat.format(msg, this.action.getState(), State.ERROR, this.action.getLocator());
|
||||
|
@ -37,6 +40,7 @@ public class ExecuteStoppedActionCommand extends ExecutionCommand {
|
|||
public void doCommand() {
|
||||
Activity rootElement = this.action.getRootElement();
|
||||
tx().lock(rootElement);
|
||||
tx().lock(getResourceLocator(this.action));
|
||||
|
||||
State currentState = rootElement.getState();
|
||||
rootElement.accept(this);
|
||||
|
|
|
@ -9,6 +9,7 @@ import li.strolch.agent.api.ComponentContainer;
|
|||
import li.strolch.exception.StrolchException;
|
||||
import li.strolch.execution.policy.ConfirmationPolicy;
|
||||
import li.strolch.execution.policy.ExecutionPolicy;
|
||||
import li.strolch.model.Locator;
|
||||
import li.strolch.model.Order;
|
||||
import li.strolch.model.Resource;
|
||||
import li.strolch.model.State;
|
||||
|
@ -29,7 +30,7 @@ public abstract class ExecutionCommand extends Command implements TimeOrderingVi
|
|||
super(container, tx);
|
||||
}
|
||||
|
||||
public static Resource getResource(StrolchTransaction tx, Action action) {
|
||||
protected Locator getResourceLocator(Action action) {
|
||||
String resourceId = action.getResourceId();
|
||||
if (StringHelper.isEmpty(resourceId) || resourceId.equals(DASH))
|
||||
throw new StrolchException("No resourceId defined on action " + action.getLocator());
|
||||
|
@ -37,7 +38,18 @@ public abstract class ExecutionCommand extends Command implements TimeOrderingVi
|
|||
if (StringHelper.isEmpty(resourceType) || resourceType.equals(DASH))
|
||||
throw new StrolchException("No resourceType defined on action " + action.getLocator());
|
||||
|
||||
return tx.getResourceBy(resourceType, resourceId, true);
|
||||
return Resource.locatorFor(resourceType, resourceId);
|
||||
}
|
||||
|
||||
protected Resource getResource(Action action) {
|
||||
String resourceId = action.getResourceId();
|
||||
if (StringHelper.isEmpty(resourceId) || resourceId.equals(DASH))
|
||||
throw new StrolchException("No resourceId defined on action " + action.getLocator());
|
||||
String resourceType = action.getResourceType();
|
||||
if (StringHelper.isEmpty(resourceType) || resourceType.equals(DASH))
|
||||
throw new StrolchException("No resourceType defined on action " + action.getLocator());
|
||||
|
||||
return tx().getResourceBy(resourceType, resourceId, true);
|
||||
}
|
||||
|
||||
protected void updateOrderState(Activity rootElement, State currentState, State newState) {
|
||||
|
@ -57,13 +69,13 @@ public abstract class ExecutionCommand extends Command implements TimeOrderingVi
|
|||
}
|
||||
|
||||
protected ExecutionPolicy getExecutionPolicy(Action action) {
|
||||
Resource resource = getResource(tx(), action);
|
||||
Resource resource = getResource(action);
|
||||
PolicyDef executionPolicyDef = resource.getPolicyDefs().getPolicyDef(ExecutionPolicy.class.getSimpleName());
|
||||
return getComponent(PolicyHandler.class).getPolicy(executionPolicyDef, tx());
|
||||
}
|
||||
|
||||
protected ConfirmationPolicy getConfirmationPolicy(Action action) {
|
||||
Resource resource = getResource(tx(), action);
|
||||
Resource resource = getResource(action);
|
||||
PolicyDef executionPolicyDef = resource.getPolicyDefs().getPolicyDef(ConfirmationPolicy.class.getSimpleName());
|
||||
return getComponent(PolicyHandler.class).getPolicy(executionPolicyDef, tx());
|
||||
}
|
||||
|
@ -150,6 +162,8 @@ public abstract class ExecutionCommand extends Command implements TimeOrderingVi
|
|||
public Void visitAction(Action action) {
|
||||
ExecutionPolicy executionPolicy = getExecutionPolicy(action);
|
||||
|
||||
tx().lock(getResourceLocator(action));
|
||||
|
||||
if (!executionPolicy.isExecutable(action)) {
|
||||
logger.info("Action " + action.getLocator() + " is not yet executable.");
|
||||
} else {
|
||||
|
|
|
@ -27,6 +27,7 @@ public class SetActionToErrorCommand extends ExecutionCommand {
|
|||
DBC.PRE.assertNotNull("action can not be null", this.action);
|
||||
|
||||
tx().lock(this.action.getRootElement());
|
||||
tx().lock(getResourceLocator(this.action));
|
||||
|
||||
if (!this.action.getState().canSetToError()) {
|
||||
String msg = "Current state is {0} and canot be changed to {1} for action {2}";
|
||||
|
@ -39,6 +40,7 @@ public class SetActionToErrorCommand extends ExecutionCommand {
|
|||
public void doCommand() {
|
||||
Activity rootElement = this.action.getRootElement();
|
||||
tx().lock(rootElement);
|
||||
tx().lock(getResourceLocator(this.action));
|
||||
|
||||
if (this.action.getState() == State.ERROR) {
|
||||
logger.warn("Action " + this.action.getLocator() + " is already in ERROR! Not changing.");
|
||||
|
|
|
@ -27,6 +27,7 @@ public class SetActionToExecutedCommand extends ExecutionCommand {
|
|||
DBC.PRE.assertNotNull("action can not be null", this.action);
|
||||
|
||||
tx().lock(this.action.getRootElement());
|
||||
tx().lock(getResourceLocator(this.action));
|
||||
|
||||
if (!this.action.getState().canSetToExecuted()) {
|
||||
String msg = "Current state is {0} canot be changed to {1} for action {2}";
|
||||
|
@ -39,6 +40,7 @@ public class SetActionToExecutedCommand extends ExecutionCommand {
|
|||
public void doCommand() {
|
||||
Activity rootElement = this.action.getRootElement();
|
||||
tx().lock(rootElement);
|
||||
tx().lock(getResourceLocator(this.action));
|
||||
|
||||
State currentState = rootElement.getState();
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ public class SetActionToStoppedCommand extends ExecutionCommand {
|
|||
DBC.PRE.assertNotNull("action can not be null", this.action);
|
||||
|
||||
tx().lock(this.action.getRootElement());
|
||||
tx().lock(getResourceLocator(this.action));
|
||||
|
||||
if (!this.action.getState().canSetToStopped()) {
|
||||
String msg = "Current state is {0} and canot be changed to {1} for action {2}";
|
||||
|
@ -39,6 +40,7 @@ public class SetActionToStoppedCommand extends ExecutionCommand {
|
|||
public void doCommand() {
|
||||
Activity rootElement = this.action.getRootElement();
|
||||
tx().lock(rootElement);
|
||||
tx().lock(getResourceLocator(this.action));
|
||||
|
||||
if (this.action.getState() == State.STOPPED) {
|
||||
logger.warn("Action " + this.action.getLocator() + " is already in STOPPED! Not changing.");
|
||||
|
|
|
@ -27,6 +27,7 @@ public class SetActionToWarningCommand extends ExecutionCommand {
|
|||
DBC.PRE.assertNotNull("action can not be null", this.action);
|
||||
|
||||
tx().lock(this.action.getRootElement());
|
||||
tx().lock(getResourceLocator(this.action));
|
||||
|
||||
if (!this.action.getState().canSetToWarning()) {
|
||||
String msg = "Current state is {0} and canot be changed to {1} for action {2}";
|
||||
|
@ -39,6 +40,7 @@ public class SetActionToWarningCommand extends ExecutionCommand {
|
|||
public void doCommand() {
|
||||
Activity rootElement = this.action.getRootElement();
|
||||
tx().lock(rootElement);
|
||||
tx().lock(getResourceLocator(this.action));
|
||||
|
||||
if (this.action.getState() == State.WARNING) {
|
||||
logger.warn("Action " + this.action.getLocator() + " is already in WARNING! Not changing.");
|
||||
|
|
|
@ -41,8 +41,6 @@ public class ReservationExection extends DurationExecution {
|
|||
@Override
|
||||
public boolean isExecutable(Action action) {
|
||||
|
||||
tx().lock(getResource(action));
|
||||
|
||||
// only check if reserve
|
||||
if (!action.getType().equals(TYPE_RESERVE) && !action.getType().equals(TYPE_RELEASE)) {
|
||||
// otherwise delegate to super class
|
||||
|
@ -71,8 +69,6 @@ public class ReservationExection extends DurationExecution {
|
|||
@Override
|
||||
public void toExecution(Action action) {
|
||||
|
||||
tx().lock(getResource(action));
|
||||
|
||||
// only do if reserve or release
|
||||
boolean isReserve = action.getType().equals(TYPE_RESERVE);
|
||||
boolean isRelease = action.getType().equals(TYPE_RELEASE);
|
||||
|
@ -95,8 +91,6 @@ public class ReservationExection extends DurationExecution {
|
|||
@Override
|
||||
public void toExecuted(Action action) {
|
||||
|
||||
tx().lock(getResource(action));
|
||||
|
||||
// only do if reserve or release
|
||||
boolean isReserve = action.getType().equals(TYPE_RESERVE);
|
||||
boolean isRelease = action.getType().equals(TYPE_RELEASE);
|
||||
|
|
Loading…
Reference in New Issue