Search in sources :

Example 11 with StateInstance

use of io.seata.saga.statelang.domain.StateInstance in project seata by seata.

the class DefaultStatusDecisionStrategy method decideMachineForwardExecutionStatus.

/**
 * Determine the forward execution state of the state machine
 *
 * @param stateMachineInstance
 * @param exp
 * @param specialPolicy
 * @return
 */
@Override
public boolean decideMachineForwardExecutionStatus(StateMachineInstance stateMachineInstance, Exception exp, boolean specialPolicy) {
    boolean result = false;
    if (stateMachineInstance.getStatus() == null || ExecutionStatus.RU.equals(stateMachineInstance.getStatus())) {
        result = true;
        List<StateInstance> stateList = stateMachineInstance.getStateList();
        setMachineStatusBasedOnStateListAndException(stateMachineInstance, stateList, exp);
        if (specialPolicy && ExecutionStatus.SU.equals(stateMachineInstance.getStatus())) {
            for (StateInstance stateInstance : stateMachineInstance.getStateList()) {
                if (!stateInstance.isIgnoreStatus() && (stateInstance.isForUpdate() || stateInstance.isForCompensation())) {
                    stateMachineInstance.setStatus(ExecutionStatus.UN);
                    break;
                }
            }
            if (ExecutionStatus.SU.equals(stateMachineInstance.getStatus())) {
                stateMachineInstance.setStatus(ExecutionStatus.FA);
            }
        }
    }
    return result;
}
Also used : StateInstance(io.seata.saga.statelang.domain.StateInstance)

Example 12 with StateInstance

use of io.seata.saga.statelang.domain.StateInstance in project seata by seata.

the class DbAndReportTcStateLogStore method findOutOriginalStateInstanceOfCompensateState.

private StateInstance findOutOriginalStateInstanceOfCompensateState(StateInstance stateInstance) {
    StateInstance originalStateInst;
    Map<String, StateInstance> stateInstanceMap = stateInstance.getStateMachineInstance().getStateMap();
    originalStateInst = stateInstance.getStateMachineInstance().getStateMap().get(stateInstance.getStateIdCompensatedFor());
    while (StringUtils.hasLength(originalStateInst.getStateIdRetriedFor())) {
        originalStateInst = stateInstanceMap.get(originalStateInst.getStateIdRetriedFor());
    }
    return originalStateInst;
}
Also used : StateInstance(io.seata.saga.statelang.domain.StateInstance)

Example 13 with StateInstance

use of io.seata.saga.statelang.domain.StateInstance in project seata by seata.

the class DbAndReportTcStateLogStore method findOutOriginalStateInstanceOfRetryState.

private StateInstance findOutOriginalStateInstanceOfRetryState(StateInstance stateInstance) {
    StateInstance originalStateInst;
    Map<String, StateInstance> stateInstanceMap = stateInstance.getStateMachineInstance().getStateMap();
    originalStateInst = stateInstanceMap.get(stateInstance.getStateIdRetriedFor());
    while (StringUtils.hasLength(originalStateInst.getStateIdRetriedFor())) {
        originalStateInst = stateInstanceMap.get(originalStateInst.getStateIdRetriedFor());
    }
    return originalStateInst;
}
Also used : StateInstance(io.seata.saga.statelang.domain.StateInstance)

Example 14 with StateInstance

use of io.seata.saga.statelang.domain.StateInstance in project seata by seata.

the class DbAndReportTcStateLogStore method generateCompensateStateInstanceId.

/**
 * generate compensate state instance id based on original state instance id
 * ${originalStateInstanceId}-${retryCount}
 * @param stateInstance
 * @return
 */
private String generateCompensateStateInstanceId(StateInstance stateInstance, boolean isUpdateMode) {
    String originalCompensateStateInstId = stateInstance.getStateIdCompensatedFor();
    int maxIndex = 1;
    // if update mode, means update last compensate inst
    if (isUpdateMode) {
        return originalCompensateStateInstId + "-" + maxIndex;
    }
    for (int i = 0; i < stateInstance.getStateMachineInstance().getStateList().size(); i++) {
        StateInstance aStateInstance = stateInstance.getStateMachineInstance().getStateList().get(i);
        if (aStateInstance != stateInstance && originalCompensateStateInstId.equals(aStateInstance.getStateIdCompensatedFor())) {
            int idIndex = getIdIndex(aStateInstance.getId(), "-");
            maxIndex = idIndex > maxIndex ? idIndex : maxIndex;
            maxIndex++;
        }
    }
    return originalCompensateStateInstId + "-" + maxIndex;
}
Also used : StateInstance(io.seata.saga.statelang.domain.StateInstance)

Example 15 with StateInstance

use of io.seata.saga.statelang.domain.StateInstance in project seata by seata.

the class ServiceTaskHandlerInterceptor method postProcess.

@Override
public void postProcess(ProcessContext context, Exception exp) throws EngineExecutionException {
    StateInstruction instruction = context.getInstruction(StateInstruction.class);
    ServiceTaskStateImpl state = (ServiceTaskStateImpl) instruction.getState(context);
    StateMachineInstance stateMachineInstance = (StateMachineInstance) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_INST);
    StateInstance stateInstance = (StateInstance) context.getVariable(DomainConstants.VAR_NAME_STATE_INST);
    if (stateInstance == null || !stateMachineInstance.isRunning()) {
        LOGGER.warn("StateMachineInstance[id:" + stateMachineInstance.getId() + "] is end. stop running");
        return;
    }
    StateMachineConfig stateMachineConfig = (StateMachineConfig) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_CONFIG);
    if (exp == null) {
        exp = (Exception) context.getVariable(DomainConstants.VAR_NAME_CURRENT_EXCEPTION);
    }
    stateInstance.setException(exp);
    decideExecutionStatus(context, stateInstance, state, exp);
    if (ExecutionStatus.SU.equals(stateInstance.getStatus()) && exp != null) {
        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("Although an exception occurs, the execution status map to SU, and the exception is ignored when " + "the execution status decision.");
        }
        context.removeVariable(DomainConstants.VAR_NAME_CURRENT_EXCEPTION);
    }
    Map<String, Object> contextVariables = (Map<String, Object>) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_CONTEXT);
    Object serviceOutputParams = context.getVariable(DomainConstants.VAR_NAME_OUTPUT_PARAMS);
    if (serviceOutputParams != null) {
        try {
            Map<String, Object> outputVariablesToContext = ParameterUtils.createOutputParams(stateMachineConfig.getExpressionFactoryManager(), state, serviceOutputParams);
            if (CollectionUtils.isNotEmpty(outputVariablesToContext)) {
                contextVariables.putAll(outputVariablesToContext);
            }
        } catch (Exception e) {
            String message = "Task [" + state.getName() + "] output parameters assign failed, please check 'Output' expression:" + e.getMessage();
            EngineExecutionException exception = ExceptionUtils.createEngineExecutionException(e, FrameworkErrorCode.VariablesAssignError, message, stateMachineInstance, stateInstance);
            if (stateMachineInstance.getStateMachine().isPersist() && state.isPersist() && stateMachineConfig.getStateLogStore() != null) {
                stateMachineConfig.getStateLogStore().recordStateFinished(stateInstance, context);
            }
            EngineUtils.failStateMachine(context, exception);
            throw exception;
        }
    }
    context.removeVariable(DomainConstants.VAR_NAME_OUTPUT_PARAMS);
    context.removeVariable(DomainConstants.VAR_NAME_INPUT_PARAMS);
    stateInstance.setGmtEnd(new Date());
    if (stateMachineInstance.getStateMachine().isPersist() && state.isPersist() && stateMachineConfig.getStateLogStore() != null) {
        stateMachineConfig.getStateLogStore().recordStateFinished(stateInstance, context);
    }
    if (exp != null && context.getVariable(DomainConstants.VAR_NAME_IS_EXCEPTION_NOT_CATCH) != null && (Boolean) context.getVariable(DomainConstants.VAR_NAME_IS_EXCEPTION_NOT_CATCH)) {
        // If there is an exception and there is no catch, need to exit the state machine to execute.
        context.removeVariable(DomainConstants.VAR_NAME_IS_EXCEPTION_NOT_CATCH);
        EngineUtils.failStateMachine(context, exp);
    }
}
Also used : StateInstruction(io.seata.saga.engine.pcext.StateInstruction) StateMachineConfig(io.seata.saga.engine.StateMachineConfig) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) EngineExecutionException(io.seata.saga.engine.exception.EngineExecutionException) EngineExecutionException(io.seata.saga.engine.exception.EngineExecutionException) Date(java.util.Date) ServiceTaskStateImpl(io.seata.saga.statelang.domain.impl.ServiceTaskStateImpl) StateMachineInstance(io.seata.saga.statelang.domain.StateMachineInstance) StateInstance(io.seata.saga.statelang.domain.StateInstance)

Aggregations

StateInstance (io.seata.saga.statelang.domain.StateInstance)31 StateMachineInstance (io.seata.saga.statelang.domain.StateMachineInstance)16 EngineExecutionException (io.seata.saga.engine.exception.EngineExecutionException)12 StateInstruction (io.seata.saga.engine.pcext.StateInstruction)11 StateMachineConfig (io.seata.saga.engine.StateMachineConfig)9 ForwardInvalidException (io.seata.saga.engine.exception.ForwardInvalidException)7 Map (java.util.Map)7 StateMachine (io.seata.saga.statelang.domain.StateMachine)5 AbstractTaskState (io.seata.saga.statelang.domain.impl.AbstractTaskState)5 ServiceTaskStateImpl (io.seata.saga.statelang.domain.impl.ServiceTaskStateImpl)5 ArrayList (java.util.ArrayList)5 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)5 HierarchicalProcessContext (io.seata.saga.proctrl.HierarchicalProcessContext)4 ExecutionStatus (io.seata.saga.statelang.domain.ExecutionStatus)4 State (io.seata.saga.statelang.domain.State)4 HashMap (java.util.HashMap)4 List (java.util.List)4 ProcessContext (io.seata.saga.proctrl.ProcessContext)3 Loop (io.seata.saga.statelang.domain.TaskState.Loop)3 LinkedHashMap (java.util.LinkedHashMap)3