From f9b1ed1582aca7fc5a980074c732832df0ed5f35 Mon Sep 17 00:00:00 2001 From: ialbert Date: Mon, 28 Jul 2025 15:31:08 +0300 Subject: [PATCH] state machine restore --- .../factory/SessionStateMachineWrapper.java | 62 +++++++++++-------- .../spcex/clearing/util/StateMachineUtil.java | 11 ++++ 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/factory/SessionStateMachineWrapper.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/factory/SessionStateMachineWrapper.java index 25a60d371..9df61f164 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/factory/SessionStateMachineWrapper.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/state/factory/SessionStateMachineWrapper.java @@ -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> 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 smFactory = getByType(sessionType); + this.currentSession = restoreSessionService.restore(smFactory, session); + prepareAndStartMachine(this.currentSession); + } + public synchronized void defineAndStartSession(BaseRequest 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 event) { @@ -141,30 +160,21 @@ public class SessionStateMachineWrapper { } - private StateMachine build( - StateMachineFactory stateMachineFactory - ) { - Session session = getPausedSession().orElse(null); - StateMachine stateMachine; - if (session != null) { - stateMachine = restoreSessionService.restore(stateMachineFactory, session); - } else { - stateMachine = stateMachineFactory.getStateMachine(); - } - stateMachine - .getStateMachineAccessor() - .doWithAllRegions( - access -> access.addStateMachineInterceptor(statusChangingInterceptor) - ); - stateMachine.getExtendedState().getVariables().put(DataEnum.ssnImdg, ssnImdg); - return stateMachine; + private void prepareAndStartMachine(StateMachine sm) { + addSmInterceptor(sm, statusChangingInterceptor); + putToSmExtState(sm, DataEnum.ssnImdg, ssnImdg); + sm.addStateListener(new MachineStopListener( + this::clearCurrentMachine) + ); + sm.start(); } private Optional 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 getPausedSession() { ImdgPredicateBuilder pb = ssnImdg.predicateBuilder(); Session existActiveSession = ssnImdg.getSingleObjectByPredicate( - pb.or( - pb.equals("workflowStatus", WorkflowStatus.Pause.getKey()) - ) + pb.equals("workflowStatus", WorkflowStatus.Pause.getKey()) ); return Optional.ofNullable(existActiveSession); } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/util/StateMachineUtil.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/util/StateMachineUtil.java index bebde801d..4fdb5450e 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/util/StateMachineUtil.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/util/StateMachineUtil.java @@ -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 void addSmInterceptor(StateMachine sm, StateMachineInterceptor smInterceptor) { + sm.getStateMachineAccessor().doWithAllRegions( + access -> access.addStateMachineInterceptor(smInterceptor) + ); + } + + public static void putToSmExtState(StateMachine sm, Object key, Object value) { + sm.getExtendedState().getVariables().put(key, value); + } + public static IllegalStateException excp(StateContext ctx, String msg) { IllegalStateException excp = new IllegalStateException(msg); ctx.getStateMachine().setStateMachineError(excp);