use of io.seata.saga.statelang.domain.impl.ServiceTaskStateImpl in project seata by seata.
the class SpringBeanServiceInvoker method doInvoke.
protected Object doInvoke(ServiceTaskStateImpl state, Object[] input) throws Throwable {
Object bean = applicationContext.getBean(state.getServiceName());
Method method = state.getMethod();
if (method == null) {
synchronized (state) {
method = state.getMethod();
if (method == null) {
method = findMethod(bean.getClass(), state.getServiceMethod(), state.getParameterTypes());
if (method != null) {
state.setMethod(method);
}
}
}
}
if (method == null) {
throw new EngineExecutionException("No such method[" + state.getServiceMethod() + "] on BeanClass[" + bean.getClass() + "]", FrameworkErrorCode.NoSuchMethod);
}
Object[] args = new Object[method.getParameterCount()];
try {
Class[] paramTypes = method.getParameterTypes();
if (input != null && input.length > 0) {
int len = input.length < paramTypes.length ? input.length : paramTypes.length;
for (int i = 0; i < len; i++) {
args[i] = toJavaObject(input[i], paramTypes[i]);
}
}
} catch (Exception e) {
throw new EngineExecutionException(e, "Input to java object error, Method[" + state.getServiceMethod() + "] on BeanClass[" + bean.getClass() + "]", FrameworkErrorCode.InvalidParameter);
}
if (!Modifier.isPublic(method.getModifiers())) {
throw new EngineExecutionException("Method[" + method.getName() + "] must be public", FrameworkErrorCode.MethodNotPublic);
}
Map<Retry, AtomicInteger> retryCountMap = new HashMap<>();
while (true) {
try {
return invokeMethod(bean, method, args);
} catch (Throwable e) {
Retry matchedRetryConfig = matchRetryConfig(state.getRetry(), e);
if (matchedRetryConfig == null) {
throw e;
}
AtomicInteger retryCount = CollectionUtils.computeIfAbsent(retryCountMap, matchedRetryConfig, key -> new AtomicInteger(0));
if (retryCount.intValue() >= matchedRetryConfig.getMaxAttempts()) {
throw e;
}
double intervalSeconds = matchedRetryConfig.getIntervalSeconds();
double backoffRate = matchedRetryConfig.getBackoffRate();
long currentInterval = (long) (retryCount.intValue() > 0 ? (intervalSeconds * backoffRate * retryCount.intValue() * 1000) : (intervalSeconds * 1000));
if (LOGGER.isWarnEnabled()) {
LOGGER.warn("Invoke Service[" + state.getServiceName() + "." + state.getServiceMethod() + "] failed, will retry after " + currentInterval + " millis, current retry count: " + retryCount.intValue(), e);
}
try {
Thread.sleep(currentInterval);
} catch (InterruptedException e1) {
LOGGER.warn("Retry interval sleep error", e1);
}
retryCount.incrementAndGet();
}
}
}
use of io.seata.saga.statelang.domain.impl.ServiceTaskStateImpl in project seata by seata.
the class ProcessCtrlStateMachineEngine method replayContextVariables.
protected Map<String, Object> replayContextVariables(StateMachineInstance stateMachineInstance) {
Map<String, Object> contextVariables = new HashMap<>();
if (stateMachineInstance.getStartParams() == null) {
contextVariables.putAll(stateMachineInstance.getStartParams());
}
List<StateInstance> stateInstanceList = stateMachineInstance.getStateList();
if (CollectionUtils.isEmpty(stateInstanceList)) {
return contextVariables;
}
for (StateInstance stateInstance : stateInstanceList) {
Object serviceOutputParams = stateInstance.getOutputParams();
if (serviceOutputParams != null) {
ServiceTaskStateImpl state = (ServiceTaskStateImpl) stateMachineInstance.getStateMachine().getState(EngineUtils.getOriginStateName(stateInstance));
if (state == null) {
throw new EngineExecutionException("Cannot find State by state name [" + stateInstance.getName() + "], may be this is a bug", FrameworkErrorCode.ObjectNotExists);
}
if (CollectionUtils.isNotEmpty(state.getOutput())) {
try {
Map<String, Object> outputVariablesToContext = ParameterUtils.createOutputParams(stateMachineConfig.getExpressionFactoryManager(), state, serviceOutputParams);
if (CollectionUtils.isNotEmpty(outputVariablesToContext)) {
contextVariables.putAll(outputVariablesToContext);
}
if (StringUtils.hasLength(stateInstance.getBusinessKey())) {
contextVariables.put(state.getName() + DomainConstants.VAR_NAME_BUSINESSKEY, stateInstance.getBusinessKey());
}
} catch (Exception e) {
throw new EngineExecutionException(e, "Context variables replay faied", FrameworkErrorCode.ContextVariableReplayFailed);
}
}
}
}
return contextVariables;
}
Aggregations