Search in sources :

Example 6 with StateMachineConfig

use of io.seata.saga.engine.StateMachineConfig in project seata by seata.

the class StateInstruction method getState.

public State getState(ProcessContext context) {
    if (getTemporaryState() != null) {
        return temporaryState;
    }
    String stateName = getStateName();
    String stateMachineName = getStateMachineName();
    String tenantId = getTenantId();
    if (StringUtils.isEmpty(stateMachineName)) {
        throw new EngineExecutionException("StateMachineName is required", FrameworkErrorCode.ParameterRequired);
    }
    StateMachineConfig stateMachineConfig = (StateMachineConfig) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_CONFIG);
    StateMachine stateMachine = stateMachineConfig.getStateMachineRepository().getStateMachine(stateMachineName, tenantId);
    if (stateMachine == null) {
        throw new EngineExecutionException("StateMachine[" + stateMachineName + "] is not exist", FrameworkErrorCode.ObjectNotExists);
    }
    if (StringUtils.isEmpty(stateName)) {
        stateName = stateMachine.getStartState();
        setStateName(stateName);
    }
    State state = stateMachine.getStates().get(stateName);
    if (state == null) {
        throw new EngineExecutionException("State[" + stateName + "] is not exist", FrameworkErrorCode.ObjectNotExists);
    }
    return state;
}
Also used : StateMachine(io.seata.saga.statelang.domain.StateMachine) State(io.seata.saga.statelang.domain.State) StateMachineConfig(io.seata.saga.engine.StateMachineConfig) EngineExecutionException(io.seata.saga.engine.exception.EngineExecutionException)

Example 7 with StateMachineConfig

use of io.seata.saga.engine.StateMachineConfig in project seata by seata.

the class CompensationTriggerStateHandler method process.

@Override
public void process(ProcessContext context) throws EngineExecutionException {
    StateInstruction instruction = context.getInstruction(StateInstruction.class);
    StateMachineInstance stateMachineInstance = (StateMachineInstance) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_INST);
    StateMachineConfig stateMachineConfig = (StateMachineConfig) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_CONFIG);
    List<StateInstance> stateInstanceList = stateMachineInstance.getStateList();
    if (CollectionUtils.isEmpty(stateInstanceList)) {
        stateInstanceList = stateMachineConfig.getStateLogStore().queryStateInstanceListByMachineInstanceId(stateMachineInstance.getId());
    }
    List<StateInstance> stateListToBeCompensated = CompensationHolder.findStateInstListToBeCompensated(context, stateInstanceList);
    if (CollectionUtils.isNotEmpty(stateListToBeCompensated)) {
        // Clear exceptions that occur during forward execution
        Exception e = (Exception) context.removeVariable(DomainConstants.VAR_NAME_CURRENT_EXCEPTION);
        if (e != null) {
            stateMachineInstance.setException(e);
        }
        Stack<StateInstance> stateStackToBeCompensated = CompensationHolder.getCurrent(context, true).getStateStackNeedCompensation();
        stateStackToBeCompensated.addAll(stateListToBeCompensated);
        // and the forward state should not be modified.
        if (stateMachineInstance.getStatus() == null || ExecutionStatus.RU.equals(stateMachineInstance.getStatus())) {
            stateMachineInstance.setStatus(ExecutionStatus.UN);
        }
        // Record the status of the state machine as "compensating", and the subsequent routing logic will route
        // to the compensation state
        stateMachineInstance.setCompensationStatus(ExecutionStatus.RU);
        context.setVariable(DomainConstants.VAR_NAME_CURRENT_COMPEN_TRIGGER_STATE, instruction.getState(context));
    } else {
        EngineUtils.endStateMachine(context);
    }
}
Also used : StateInstruction(io.seata.saga.engine.pcext.StateInstruction) StateMachineConfig(io.seata.saga.engine.StateMachineConfig) EngineExecutionException(io.seata.saga.engine.exception.EngineExecutionException) StateMachineInstance(io.seata.saga.statelang.domain.StateMachineInstance) StateInstance(io.seata.saga.statelang.domain.StateInstance)

Example 8 with StateMachineConfig

use of io.seata.saga.engine.StateMachineConfig in project seata by seata.

the class ScriptTaskStateHandler method process.

@Override
public void process(ProcessContext context) throws EngineExecutionException {
    StateInstruction instruction = context.getInstruction(StateInstruction.class);
    ScriptTaskStateImpl state = (ScriptTaskStateImpl) instruction.getState(context);
    String scriptType = state.getScriptType();
    String scriptContent = state.getScriptContent();
    Object result;
    try {
        List<Object> input = (List<Object>) context.getVariable(DomainConstants.VAR_NAME_INPUT_PARAMS);
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug(">>>>>>>>>>>>>>>>>>>>>> Start to execute ScriptTaskState[{}], ScriptType[{}], Input:{}", state.getName(), scriptType, input);
        }
        StateMachineConfig stateMachineConfig = (StateMachineConfig) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_CONFIG);
        ScriptEngine scriptEngine = getScriptEngineFromCache(scriptType, stateMachineConfig.getScriptEngineManager());
        if (scriptEngine == null) {
            throw new EngineExecutionException("No such ScriptType[" + scriptType + "]", FrameworkErrorCode.ObjectNotExists);
        }
        Bindings bindings = null;
        Map<String, Object> inputMap = null;
        if (CollectionUtils.isNotEmpty(input) && input.get(0) instanceof Map) {
            inputMap = (Map<String, Object>) input.get(0);
        }
        List<Object> inputExps = state.getInput();
        if (CollectionUtils.isNotEmpty(inputExps) && inputExps.get(0) instanceof Map) {
            Map<String, Object> inputExpMap = (Map<String, Object>) inputExps.get(0);
            if (inputExpMap.size() > 0) {
                bindings = new SimpleBindings();
                for (String property : inputExpMap.keySet()) {
                    if (inputMap != null && inputMap.containsKey(property)) {
                        bindings.put(property, inputMap.get(property));
                    } else {
                        // if we do not bind the null value property, groovy will throw MissingPropertyException
                        bindings.put(property, null);
                    }
                }
            }
        }
        if (bindings != null) {
            result = scriptEngine.eval(scriptContent, bindings);
        } else {
            result = scriptEngine.eval(scriptContent);
        }
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("<<<<<<<<<<<<<<<<<<<<<< ScriptTaskState[{}], ScriptType[{}], Execute finish. result: {}", state.getName(), scriptType, result);
        }
        if (result != null) {
            ((HierarchicalProcessContext) context).setVariableLocally(DomainConstants.VAR_NAME_OUTPUT_PARAMS, result);
        }
    } catch (Throwable e) {
        LOGGER.error("<<<<<<<<<<<<<<<<<<<<<< ScriptTaskState[{}], ScriptTaskState[{}] Execute failed.", state.getName(), scriptType, e);
        ((HierarchicalProcessContext) context).setVariableLocally(DomainConstants.VAR_NAME_CURRENT_EXCEPTION, e);
        EngineUtils.handleException(context, state, e);
    }
}
Also used : StateInstruction(io.seata.saga.engine.pcext.StateInstruction) HierarchicalProcessContext(io.seata.saga.proctrl.HierarchicalProcessContext) EngineExecutionException(io.seata.saga.engine.exception.EngineExecutionException) Bindings(javax.script.Bindings) SimpleBindings(javax.script.SimpleBindings) ScriptEngine(javax.script.ScriptEngine) ScriptTaskStateImpl(io.seata.saga.statelang.domain.impl.ScriptTaskStateImpl) SimpleBindings(javax.script.SimpleBindings) ArrayList(java.util.ArrayList) List(java.util.List) StateMachineConfig(io.seata.saga.engine.StateMachineConfig) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Map(java.util.Map)

Example 9 with StateMachineConfig

use of io.seata.saga.engine.StateMachineConfig in project seata by seata.

the class DbAndReportTcStateLogStore method beginTransaction.

protected void beginTransaction(StateMachineInstance machineInstance, ProcessContext context) {
    if (sagaTransactionalTemplate != null) {
        StateMachineConfig stateMachineConfig = (StateMachineConfig) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_CONFIG);
        TransactionInfo transactionInfo = new TransactionInfo();
        transactionInfo.setTimeOut(stateMachineConfig.getTransOperationTimeout());
        transactionInfo.setName(Constants.SAGA_TRANS_NAME_PREFIX + machineInstance.getStateMachine().getName());
        try {
            GlobalTransaction globalTransaction = sagaTransactionalTemplate.beginTransaction(transactionInfo);
            machineInstance.setId(globalTransaction.getXid());
            context.setVariable(DomainConstants.VAR_NAME_GLOBAL_TX, globalTransaction);
            Map<String, Object> machineContext = machineInstance.getContext();
            if (machineContext != null) {
                machineContext.put(DomainConstants.VAR_NAME_GLOBAL_TX, globalTransaction);
            }
        } catch (ExecutionException e) {
            String xid = null;
            if (e.getTransaction() != null) {
                xid = e.getTransaction().getXid();
            }
            throw new EngineExecutionException(e, e.getCode() + ", TransName:" + transactionInfo.getName() + ", XID: " + xid + ", Reason: " + e.getMessage(), FrameworkErrorCode.TransactionManagerError);
        } finally {
            if (Boolean.TRUE.equals(context.getVariable(DomainConstants.VAR_NAME_IS_ASYNC_EXECUTION))) {
                RootContext.unbind();
                RootContext.unbindBranchType();
            }
        }
    }
}
Also used : TransactionInfo(io.seata.tm.api.transaction.TransactionInfo) GlobalTransaction(io.seata.tm.api.GlobalTransaction) DbStateMachineConfig(io.seata.saga.engine.config.DbStateMachineConfig) DefaultStateMachineConfig(io.seata.saga.engine.impl.DefaultStateMachineConfig) StateMachineConfig(io.seata.saga.engine.StateMachineConfig) EngineExecutionException(io.seata.saga.engine.exception.EngineExecutionException) ExecutionException(io.seata.tm.api.TransactionalExecutor.ExecutionException) EngineExecutionException(io.seata.saga.engine.exception.EngineExecutionException)

Example 10 with StateMachineConfig

use of io.seata.saga.engine.StateMachineConfig in project seata by seata.

the class DbAndReportTcStateLogStore method recordStateFinished.

@Override
public void recordStateFinished(StateInstance stateInstance, ProcessContext context) {
    if (stateInstance != null) {
        stateInstance.setSerializedOutputParams(paramsSerializer.serialize(stateInstance.getOutputParams()));
        stateInstance.setSerializedException(exceptionSerializer.serialize(stateInstance.getException()));
        executeUpdate(stateLogStoreSqls.getRecordStateFinishedSql(dbType), STATE_INSTANCE_TO_STATEMENT_FOR_UPDATE, stateInstance);
        // A switch to skip branch report on branch success, in order to optimize performance
        StateMachineConfig stateMachineConfig = (StateMachineConfig) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_CONFIG);
        if (!(stateMachineConfig instanceof DbStateMachineConfig && !((DbStateMachineConfig) stateMachineConfig).isRmReportSuccessEnable() && ExecutionStatus.SU.equals(stateInstance.getStatus()))) {
            branchReport(stateInstance, context);
        }
    }
}
Also used : DbStateMachineConfig(io.seata.saga.engine.config.DbStateMachineConfig) DefaultStateMachineConfig(io.seata.saga.engine.impl.DefaultStateMachineConfig) StateMachineConfig(io.seata.saga.engine.StateMachineConfig) DbStateMachineConfig(io.seata.saga.engine.config.DbStateMachineConfig)

Aggregations

StateMachineConfig (io.seata.saga.engine.StateMachineConfig)24 StateMachineInstance (io.seata.saga.statelang.domain.StateMachineInstance)15 EngineExecutionException (io.seata.saga.engine.exception.EngineExecutionException)14 StateInstruction (io.seata.saga.engine.pcext.StateInstruction)11 StateInstance (io.seata.saga.statelang.domain.StateInstance)8 Map (java.util.Map)8 DbStateMachineConfig (io.seata.saga.engine.config.DbStateMachineConfig)5 DefaultStateMachineConfig (io.seata.saga.engine.impl.DefaultStateMachineConfig)5 HierarchicalProcessContext (io.seata.saga.proctrl.HierarchicalProcessContext)5 ArrayList (java.util.ArrayList)5 Date (java.util.Date)5 ScriptTaskStateImpl (io.seata.saga.statelang.domain.impl.ScriptTaskStateImpl)3 ServiceTaskStateImpl (io.seata.saga.statelang.domain.impl.ServiceTaskStateImpl)3 GlobalTransaction (io.seata.tm.api.GlobalTransaction)3 ExecutionException (io.seata.tm.api.TransactionalExecutor.ExecutionException)3 LinkedHashMap (java.util.LinkedHashMap)3 List (java.util.List)3 TransactionException (io.seata.core.exception.TransactionException)2 AsyncCallback (io.seata.saga.engine.AsyncCallback)2 ExpressionEvaluator (io.seata.saga.engine.evaluation.expression.ExpressionEvaluator)2