state machine restore

This commit is contained in:
ialbert 2025-07-28 15:31:08 +03:00
parent 06e133421d
commit f9b1ed1582
2 changed files with 46 additions and 27 deletions

View file

@ -6,6 +6,7 @@ import java.util.Optional;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.statemachine.StateMachine;
@ -22,6 +23,8 @@ import ru.spcex.clearing.session.state.DataEnum;
import ru.spcex.clearing.session.state.SsnEvent;
import ru.spcex.clearing.session.state.interceptor.SessionStatusChangingInterceptor;
import ru.spcex.clearing.session.state.listener.MachineStopListener;
import static ru.spcex.clearing.util.StateMachineUtil.addSmInterceptor;
import static ru.spcex.clearing.util.StateMachineUtil.putToSmExtState;
import ru.spcex.platform.enumeration.ObjectType;
import ru.spcex.platform.enumeration.Priority;
import ru.spcex.platform.enumeration.Section;
@ -36,7 +39,7 @@ import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.error.ValidationException;
@Component
public class SessionStateMachineWrapper {
public class SessionStateMachineWrapper implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final Map<SessionType, StateMachineFactory<TaskType, SsnEvent>> factories;
@ -71,6 +74,25 @@ public class SessionStateMachineWrapper {
this.restoreSessionService = restoreSessionService;
}
@Override
public void afterPropertiesSet() throws Exception {
Session session = getPausedSession().orElse(null);
if (session == null) {
log.info("no paused session found on startup");
return;
}
log.info("found paused session on startup: {}.id={}",
session.getSessionType(),
session.getId());
SessionType sessionType = IEnumKey.getEnumByKey(SessionType.class, session.getSessionType());
if (sessionType == null) {
throw new IllegalStateException("unknown session type " + session.getSessionType());
}
StateMachineFactory<TaskType, SsnEvent> smFactory = getByType(sessionType);
this.currentSession = restoreSessionService.restore(smFactory, session);
prepareAndStartMachine(this.currentSession);
}
public synchronized void defineAndStartSession(BaseRequest<LauncherCommandRequest> r) throws ValidationException {
LauncherCommandRequest payload = r.getRequestPayload();
SessionType sessionType = IEnumKey.getEnumByKey(SessionType.class, payload.getSessionType());
@ -106,11 +128,8 @@ public class SessionStateMachineWrapper {
throw new ValidationException(err);
}
this.currentSession = build(factory);
this.currentSession.addStateListener(new MachineStopListener(
this::clearCurrentMachine
));
this.currentSession.start();
this.currentSession = factory.getStateMachine();
prepareAndStartMachine(currentSession);
}
public synchronized void sendEvent(Message<SsnEvent> event) {
@ -141,30 +160,21 @@ public class SessionStateMachineWrapper {
}
private StateMachine<TaskType, SsnEvent> build(
StateMachineFactory<TaskType, SsnEvent> stateMachineFactory
) {
Session session = getPausedSession().orElse(null);
StateMachine<TaskType, SsnEvent> stateMachine;
if (session != null) {
stateMachine = restoreSessionService.restore(stateMachineFactory, session);
} else {
stateMachine = stateMachineFactory.getStateMachine();
}
stateMachine
.getStateMachineAccessor()
.doWithAllRegions(
access -> access.addStateMachineInterceptor(statusChangingInterceptor)
private void prepareAndStartMachine(StateMachine<TaskType, SsnEvent> sm) {
addSmInterceptor(sm, statusChangingInterceptor);
putToSmExtState(sm, DataEnum.ssnImdg, ssnImdg);
sm.addStateListener(new MachineStopListener(
this::clearCurrentMachine)
);
stateMachine.getExtendedState().getVariables().put(DataEnum.ssnImdg, ssnImdg);
return stateMachine;
sm.start();
}
private Optional<Session> getActiveSession() {
ImdgPredicateBuilder pb = ssnImdg.predicateBuilder();
Session existActiveSession = ssnImdg.getSingleObjectByPredicate(
pb.or(
pb.equals("workflowStatus", WorkflowStatus.Active.getKey())
pb.equals("workflowStatus", WorkflowStatus.Active.getKey()),
pb.equals("workflowStatus", WorkflowStatus.Pause.getKey())
)
);
return Optional.ofNullable(existActiveSession);
@ -173,9 +183,7 @@ public class SessionStateMachineWrapper {
private Optional<Session> getPausedSession() {
ImdgPredicateBuilder pb = ssnImdg.predicateBuilder();
Session existActiveSession = ssnImdg.getSingleObjectByPredicate(
pb.or(
pb.equals("workflowStatus", WorkflowStatus.Pause.getKey())
)
);
return Optional.ofNullable(existActiveSession);
}

View file

@ -5,6 +5,7 @@ import org.springframework.statemachine.StateContext;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.guard.Guard;
import org.springframework.statemachine.support.StateMachineInterceptor;
import ru.spcex.clearing.session.state.DataEnum;
public class StateMachineUtil {
@ -38,6 +39,16 @@ public class StateMachineUtil {
};
}
public static <S, E> void addSmInterceptor(StateMachine<S, E> sm, StateMachineInterceptor<S, E> smInterceptor) {
sm.getStateMachineAccessor().doWithAllRegions(
access -> access.addStateMachineInterceptor(smInterceptor)
);
}
public static <S, E> void putToSmExtState(StateMachine<S, E> sm, Object key, Object value) {
sm.getExtendedState().getVariables().put(key, value);
}
public static <T1, T2> IllegalStateException excp(StateContext<T1, T2> ctx, String msg) {
IllegalStateException excp = new IllegalStateException(msg);
ctx.getStateMachine().setStateMachineError(excp);