use of io.seata.saga.statelang.domain.CompensateSubStateMachineState in project seata by seata.
the class TaskStateRouter method compensateRoute.
private Instruction compensateRoute(ProcessContext context, State compensationTriggerState) {
// and the compensation process is interrupted.
if (Boolean.TRUE.equals(context.getVariable(DomainConstants.VAR_NAME_FIRST_COMPENSATION_STATE_STARTED))) {
Exception exception = (Exception) context.getVariable(DomainConstants.VAR_NAME_CURRENT_EXCEPTION);
if (exception != null) {
EngineUtils.endStateMachine(context);
return null;
}
StateInstance stateInstance = (StateInstance) context.getVariable(DomainConstants.VAR_NAME_STATE_INST);
if (stateInstance != null && (!ExecutionStatus.SU.equals(stateInstance.getStatus()))) {
EngineUtils.endStateMachine(context);
return null;
}
}
Stack<StateInstance> stateStackToBeCompensated = CompensationHolder.getCurrent(context, true).getStateStackNeedCompensation();
if (!stateStackToBeCompensated.isEmpty()) {
StateInstance stateToBeCompensated = stateStackToBeCompensated.pop();
StateMachine stateMachine = (StateMachine) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE);
State state = stateMachine.getState(EngineUtils.getOriginStateName(stateToBeCompensated));
if (state != null && state instanceof AbstractTaskState) {
AbstractTaskState taskState = (AbstractTaskState) state;
StateInstruction instruction = context.getInstruction(StateInstruction.class);
State compensateState = null;
String compensateStateName = taskState.getCompensateState();
if (StringUtils.hasLength(compensateStateName)) {
compensateState = stateMachine.getState(compensateStateName);
}
if (compensateState == null && (taskState instanceof SubStateMachine)) {
compensateState = ((SubStateMachine) taskState).getCompensateStateObject();
instruction.setTemporaryState(compensateState);
}
if (compensateState == null) {
EngineUtils.endStateMachine(context);
return null;
}
instruction.setStateName(compensateState.getName());
CompensationHolder.getCurrent(context, true).addToBeCompensatedState(compensateState.getName(), stateToBeCompensated);
((HierarchicalProcessContext) context).setVariableLocally(DomainConstants.VAR_NAME_FIRST_COMPENSATION_STATE_STARTED, true);
if (compensateState instanceof CompensateSubStateMachineState) {
((HierarchicalProcessContext) context).setVariableLocally(compensateState.getName() + DomainConstants.VAR_NAME_SUB_MACHINE_PARENT_ID, EngineUtils.generateParentId(stateToBeCompensated));
}
return instruction;
}
}
context.removeVariable(DomainConstants.VAR_NAME_CURRENT_COMPEN_TRIGGER_STATE);
String compensationTriggerStateNext = compensationTriggerState.getNext();
if (StringUtils.isEmpty(compensationTriggerStateNext)) {
EngineUtils.endStateMachine(context);
return null;
}
StateInstruction instruction = context.getInstruction(StateInstruction.class);
instruction.setStateName(compensationTriggerStateNext);
return instruction;
}
use of io.seata.saga.statelang.domain.CompensateSubStateMachineState in project seata by seata.
the class ServiceTaskStateHandler method process.
@Override
public void process(ProcessContext context) throws EngineExecutionException {
StateInstruction instruction = context.getInstruction(StateInstruction.class);
ServiceTaskStateImpl state = (ServiceTaskStateImpl) instruction.getState(context);
String serviceName = state.getServiceName();
String methodName = state.getServiceMethod();
StateInstance stateInstance = (StateInstance) context.getVariable(DomainConstants.VAR_NAME_STATE_INST);
Object result;
try {
List<Object> input = (List<Object>) context.getVariable(DomainConstants.VAR_NAME_INPUT_PARAMS);
// Set the current task execution status to RU (Running)
stateInstance.setStatus(ExecutionStatus.RU);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(">>>>>>>>>>>>>>>>>>>>>> Start to execute State[{}], ServiceName[{}], Method[{}], Input:{}", state.getName(), serviceName, methodName, input);
}
if (state instanceof CompensateSubStateMachineState) {
// If it is the compensation of the substate machine,
// directly call the state machine's compensate method
result = compensateSubStateMachine(context, state, input, stateInstance, (StateMachineEngine) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_ENGINE));
} else {
StateMachineConfig stateMachineConfig = (StateMachineConfig) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_CONFIG);
ServiceInvoker serviceInvoker = stateMachineConfig.getServiceInvokerManager().getServiceInvoker(state.getServiceType());
if (serviceInvoker == null) {
throw new EngineExecutionException("No such ServiceInvoker[" + state.getServiceType() + "]", FrameworkErrorCode.ObjectNotExists);
}
if (serviceInvoker instanceof ApplicationContextAware) {
((ApplicationContextAware) serviceInvoker).setApplicationContext(stateMachineConfig.getApplicationContext());
}
result = serviceInvoker.invoke(state, input.toArray());
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("<<<<<<<<<<<<<<<<<<<<<< State[{}], ServiceName[{}], Method[{}] Execute finish. result: {}", state.getName(), serviceName, methodName, result);
}
if (result != null) {
stateInstance.setOutputParams(result);
((HierarchicalProcessContext) context).setVariableLocally(DomainConstants.VAR_NAME_OUTPUT_PARAMS, result);
}
} catch (Throwable e) {
LOGGER.error("<<<<<<<<<<<<<<<<<<<<<< State[{}], ServiceName[{}], Method[{}] Execute failed.", state.getName(), serviceName, methodName, e);
((HierarchicalProcessContext) context).setVariableLocally(DomainConstants.VAR_NAME_CURRENT_EXCEPTION, e);
EngineUtils.handleException(context, state, e);
}
}
Aggregations