Search in sources :

Example 6 with EngineExecutionException

use of io.seata.saga.engine.exception.EngineExecutionException in project seata by seata.

the class ProcessCtrlStateMachineEngine method reloadStateMachineInstance.

/**
 * override state machine instance
 *
 * @param instId
 * @return
 */
@Override
public StateMachineInstance reloadStateMachineInstance(String instId) {
    StateMachineInstance inst = stateMachineConfig.getStateLogStore().getStateMachineInstance(instId);
    if (inst != null) {
        StateMachine stateMachine = inst.getStateMachine();
        if (stateMachine == null) {
            stateMachine = stateMachineConfig.getStateMachineRepository().getStateMachineById(inst.getMachineId());
            inst.setStateMachine(stateMachine);
        }
        if (stateMachine == null) {
            throw new EngineExecutionException("StateMachine[id:" + inst.getMachineId() + "] not exist.", FrameworkErrorCode.ObjectNotExists);
        }
        List<StateInstance> stateList = inst.getStateList();
        if (CollectionUtils.isEmpty(stateList)) {
            stateList = stateMachineConfig.getStateLogStore().queryStateInstanceListByMachineInstanceId(instId);
            if (CollectionUtils.isNotEmpty(stateList)) {
                for (StateInstance tmpStateInstance : stateList) {
                    inst.putStateInstance(tmpStateInstance.getId(), tmpStateInstance);
                }
            }
        }
        if (CollectionUtils.isEmpty(inst.getEndParams())) {
            inst.setEndParams(replayContextVariables(inst));
        }
    }
    return inst;
}
Also used : StateMachine(io.seata.saga.statelang.domain.StateMachine) EngineExecutionException(io.seata.saga.engine.exception.EngineExecutionException) StateMachineInstance(io.seata.saga.statelang.domain.StateMachineInstance) StateInstance(io.seata.saga.statelang.domain.StateInstance)

Example 7 with EngineExecutionException

use of io.seata.saga.engine.exception.EngineExecutionException in project seata by seata.

the class ProcessCtrlStateMachineEngine method createMachineInstance.

private StateMachineInstance createMachineInstance(String stateMachineName, String tenantId, String businessKey, Map<String, Object> startParams) {
    StateMachine stateMachine = stateMachineConfig.getStateMachineRepository().getStateMachine(stateMachineName, tenantId);
    if (stateMachine == null) {
        throw new EngineExecutionException("StateMachine[" + stateMachineName + "] is not exists", FrameworkErrorCode.ObjectNotExists);
    }
    StateMachineInstanceImpl inst = new StateMachineInstanceImpl();
    inst.setStateMachine(stateMachine);
    inst.setMachineId(stateMachine.getId());
    inst.setTenantId(tenantId);
    inst.setBusinessKey(businessKey);
    inst.setStartParams(startParams);
    if (startParams != null) {
        if (StringUtils.hasText(businessKey)) {
            startParams.put(DomainConstants.VAR_NAME_BUSINESSKEY, businessKey);
        }
        String parentId = (String) startParams.get(DomainConstants.VAR_NAME_PARENT_ID);
        if (StringUtils.hasText(parentId)) {
            inst.setParentId(parentId);
            startParams.remove(DomainConstants.VAR_NAME_PARENT_ID);
        }
    }
    inst.setStatus(ExecutionStatus.RU);
    inst.setRunning(true);
    inst.setGmtStarted(new Date());
    inst.setGmtUpdated(inst.getGmtStarted());
    return inst;
}
Also used : StateMachine(io.seata.saga.statelang.domain.StateMachine) StateMachineInstanceImpl(io.seata.saga.statelang.domain.impl.StateMachineInstanceImpl) EngineExecutionException(io.seata.saga.engine.exception.EngineExecutionException) Date(java.util.Date)

Example 8 with EngineExecutionException

use of io.seata.saga.engine.exception.EngineExecutionException in project seata by seata.

the class SubStateMachineHandler method process.

@Override
public void process(ProcessContext context) throws EngineExecutionException {
    StateInstruction instruction = context.getInstruction(StateInstruction.class);
    SubStateMachineImpl subStateMachine = (SubStateMachineImpl) instruction.getState(context);
    StateMachineEngine engine = (StateMachineEngine) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_ENGINE);
    StateMachineInstance stateMachineInstance = (StateMachineInstance) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_INST);
    StateInstance stateInstance = (StateInstance) context.getVariable(DomainConstants.VAR_NAME_STATE_INST);
    Object inputParamsObj = context.getVariable(DomainConstants.VAR_NAME_INPUT_PARAMS);
    Map<String, Object> startParams = new HashMap<>(0);
    if (inputParamsObj instanceof List) {
        List<Object> listInputParams = (List<Object>) inputParamsObj;
        if (listInputParams.size() > 0) {
            startParams = (Map<String, Object>) listInputParams.get(0);
        }
    } else if (inputParamsObj instanceof Map) {
        startParams = (Map<String, Object>) inputParamsObj;
    }
    startParams.put(DomainConstants.VAR_NAME_PARENT_ID, EngineUtils.generateParentId(stateInstance));
    try {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug(">>>>>>>>>>>>>>>>>>>>>> Start to execute SubStateMachine [{}] by state[{}]", subStateMachine.getStateMachineName(), subStateMachine.getName());
        }
        StateMachineInstance subStateMachineInstance = callSubStateMachine(startParams, engine, context, stateInstance, subStateMachine);
        Map<String, Object> outputParams = subStateMachineInstance.getEndParams();
        boolean isForward = DomainConstants.OPERATION_NAME_FORWARD.equals(context.getVariable(DomainConstants.VAR_NAME_OPERATION_NAME));
        ExecutionStatus callSubMachineStatus = decideStatus(subStateMachineInstance, isForward);
        stateInstance.setStatus(callSubMachineStatus);
        outputParams.put(DomainConstants.VAR_NAME_SUB_STATEMACHINE_EXEC_STATUE, callSubMachineStatus.toString());
        context.setVariable(DomainConstants.VAR_NAME_OUTPUT_PARAMS, outputParams);
        stateInstance.setOutputParams(outputParams);
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("<<<<<<<<<<<<<<<<<<<<<< SubStateMachine[{}] execute finish with status[{}], compensateStatus[{}]", subStateMachine.getStateMachineName(), subStateMachineInstance.getStatus(), subStateMachineInstance.getCompensationStatus());
        }
    } catch (Exception e) {
        LOGGER.error("SubStateMachine[{}] execute failed by state[name:{}]", subStateMachine.getStateMachineName(), subStateMachine.getName(), e);
        if (e instanceof ForwardInvalidException) {
            String retriedId = stateInstance.getStateIdRetriedFor();
            StateInstance stateToBeRetried = null;
            for (StateInstance stateInst : stateMachineInstance.getStateList()) {
                if (retriedId.equals(stateInst.getId())) {
                    stateToBeRetried = stateInst;
                    break;
                }
            }
            if (stateToBeRetried != null) {
                stateInstance.setStatus(stateToBeRetried.getStatus());
            }
        }
        context.setVariable(DomainConstants.VAR_NAME_CURRENT_EXCEPTION, e);
        EngineUtils.handleException(context, subStateMachine, e);
    }
}
Also used : StateMachineEngine(io.seata.saga.engine.StateMachineEngine) StateInstruction(io.seata.saga.engine.pcext.StateInstruction) HashMap(java.util.HashMap) ForwardInvalidException(io.seata.saga.engine.exception.ForwardInvalidException) EngineExecutionException(io.seata.saga.engine.exception.EngineExecutionException) ForwardInvalidException(io.seata.saga.engine.exception.ForwardInvalidException) StateMachineInstance(io.seata.saga.statelang.domain.StateMachineInstance) ExecutionStatus(io.seata.saga.statelang.domain.ExecutionStatus) ArrayList(java.util.ArrayList) List(java.util.List) SubStateMachineImpl(io.seata.saga.statelang.domain.impl.SubStateMachineImpl) HashMap(java.util.HashMap) Map(java.util.Map) StateInstance(io.seata.saga.statelang.domain.StateInstance)

Example 9 with EngineExecutionException

use of io.seata.saga.engine.exception.EngineExecutionException in project seata by seata.

the class CompensationHolder method findStateInstListToBeCompensated.

public static List<StateInstance> findStateInstListToBeCompensated(ProcessContext context, List<StateInstance> stateInstanceList) {
    List<StateInstance> stateListToBeCompensated = null;
    if (CollectionUtils.isNotEmpty(stateInstanceList)) {
        stateListToBeCompensated = new ArrayList<>(stateInstanceList.size());
        StateMachine stateMachine = (StateMachine) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE);
        StateMachineInstance stateMachineInstance = (StateMachineInstance) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_INST);
        for (StateInstance stateInstance : stateInstanceList) {
            if (stateNeedToCompensate(stateInstance)) {
                State state = stateMachine.getState(EngineUtils.getOriginStateName(stateInstance));
                AbstractTaskState taskState = null;
                if (state instanceof AbstractTaskState) {
                    taskState = (AbstractTaskState) state;
                }
                // The state machine needs to exit directly without compensation.
                if (stateInstance.isForUpdate() && taskState != null && StringUtils.isBlank(taskState.getCompensateState())) {
                    String message = "StateMachineInstance[" + stateMachineInstance.getId() + ":" + stateMachine.getName() + "] have a state [" + stateInstance.getName() + "] is a service for update data, but no compensateState found.";
                    EngineExecutionException exception = ExceptionUtils.createEngineExecutionException(FrameworkErrorCode.CompensationStateNotFound, message, stateMachineInstance, stateInstance);
                    EngineUtils.failStateMachine(context, exception);
                    throw exception;
                }
                if (taskState != null && StringUtils.isNotBlank(taskState.getCompensateState())) {
                    stateListToBeCompensated.add(stateInstance);
                }
            }
        }
    }
    return stateListToBeCompensated;
}
Also used : AbstractTaskState(io.seata.saga.statelang.domain.impl.AbstractTaskState) StateMachine(io.seata.saga.statelang.domain.StateMachine) State(io.seata.saga.statelang.domain.State) AbstractTaskState(io.seata.saga.statelang.domain.impl.AbstractTaskState) EngineExecutionException(io.seata.saga.engine.exception.EngineExecutionException) StateInstance(io.seata.saga.statelang.domain.StateInstance) StateMachineInstance(io.seata.saga.statelang.domain.StateMachineInstance)

Example 10 with EngineExecutionException

use of io.seata.saga.engine.exception.EngineExecutionException in project seata by seata.

the class DbAndReportTcStateLogStore method recordStateMachineRestarted.

@Override
public void recordStateMachineRestarted(StateMachineInstance machineInstance, ProcessContext context) {
    if (machineInstance != null) {
        // save to db
        Date gmtUpdated = new Date();
        int effect = executeUpdate(stateLogStoreSqls.getUpdateStateMachineRunningStatusSql(dbType), machineInstance.isRunning(), new Timestamp(gmtUpdated.getTime()), machineInstance.getId(), new Timestamp(machineInstance.getGmtUpdated().getTime()));
        if (effect < 1) {
            throw new EngineExecutionException("StateMachineInstance [id:" + machineInstance.getId() + "] is recovered by an other execution, restart denied", FrameworkErrorCode.OperationDenied);
        }
        machineInstance.setGmtUpdated(gmtUpdated);
    }
}
Also used : Timestamp(java.sql.Timestamp) EngineExecutionException(io.seata.saga.engine.exception.EngineExecutionException) Date(java.util.Date)

Aggregations

EngineExecutionException (io.seata.saga.engine.exception.EngineExecutionException)34 StateMachineInstance (io.seata.saga.statelang.domain.StateMachineInstance)20 StateMachineConfig (io.seata.saga.engine.StateMachineConfig)14 StateInstruction (io.seata.saga.engine.pcext.StateInstruction)14 StateInstance (io.seata.saga.statelang.domain.StateInstance)11 Map (java.util.Map)10 GlobalTransaction (io.seata.tm.api.GlobalTransaction)6 ArrayList (java.util.ArrayList)6 HierarchicalProcessContext (io.seata.saga.proctrl.HierarchicalProcessContext)5 ServiceTaskStateImpl (io.seata.saga.statelang.domain.impl.ServiceTaskStateImpl)5 Date (java.util.Date)5 List (java.util.List)5 TransactionException (io.seata.core.exception.TransactionException)4 ForwardInvalidException (io.seata.saga.engine.exception.ForwardInvalidException)4 ProcessContext (io.seata.saga.proctrl.ProcessContext)4 ExecutionStatus (io.seata.saga.statelang.domain.ExecutionStatus)4 State (io.seata.saga.statelang.domain.State)4 StateMachine (io.seata.saga.statelang.domain.StateMachine)4 ExecutionException (io.seata.tm.api.TransactionalExecutor.ExecutionException)4 HashMap (java.util.HashMap)4