Change machine lifecycle with restore
- Fixing machine lifecycle logic when machine is restored which effectively should not touch any lifecycle methods as start/stop is user level action. - Remove start/stop from restore and attempt to do same when root machine is started. This also needed some further changes as some functionality for restore was essentially broken - Fixes #386
This commit is contained in:
@@ -355,6 +355,15 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
// dispatched via executor
|
||||
StateContext<S, E> stateContext = buildStateContext(Stage.STATEMACHINE_START, null, null, getRelayStateMachine());
|
||||
notifyStateMachineStarted(stateContext);
|
||||
if (currentState != null && currentState.isSubmachineState()) {
|
||||
StateMachine<S, E> submachine = ((AbstractState<S, E>)currentState).getSubmachine();
|
||||
submachine.start();
|
||||
} else if (currentState != null && currentState.isOrthogonal()) {
|
||||
Collection<Region<S, E>> regions = ((AbstractState<S, E>)currentState).getRegions();
|
||||
for (Region<S, E> region : regions) {
|
||||
region.start();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
registerPseudoStateListener();
|
||||
@@ -613,7 +622,6 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
}
|
||||
});
|
||||
}
|
||||
submachine.start();
|
||||
} else if (s.isOrthogonal() && stateMachineContext.getChilds() != null) {
|
||||
Collection<Region<S, E>> regions = ((AbstractState<S, E>)s).getRegions();
|
||||
for (Region<S, E> region : regions) {
|
||||
@@ -627,9 +635,6 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
});
|
||||
}
|
||||
}
|
||||
for (Region<S, E> region : regions) {
|
||||
region.start();
|
||||
}
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
@@ -652,8 +657,15 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
});
|
||||
}
|
||||
}
|
||||
for (Region<S, E> region : regions) {
|
||||
region.start();
|
||||
} else {
|
||||
for (final StateMachineContext<S, E> child : stateMachineContext.getChilds()) {
|
||||
S state2 = child.getState();
|
||||
if (state2 != null && ss.getIds().contains(state2)) {
|
||||
currentState = s;
|
||||
lastState = currentState;
|
||||
stateSet = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -951,23 +963,23 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
}
|
||||
State<S, E> notifyFrom = currentState;
|
||||
currentState = state;
|
||||
if (!isRunning()) {
|
||||
start();
|
||||
}
|
||||
entryToState(state, message, transition, stateMachine);
|
||||
notifyStateChanged(buildStateContext(Stage.STATE_CHANGED, message, null, getRelayStateMachine(), notifyFrom, state));
|
||||
nonDeepStatePresent = true;
|
||||
if (!isRunning() && !isComplete()) {
|
||||
start();
|
||||
}
|
||||
} else if (currentState == null && StateMachineUtils.isSubstate(findDeep, state)) {
|
||||
if (exit) {
|
||||
exitCurrentState(findDeep, message, transition, stateMachine, sources, targets);
|
||||
}
|
||||
State<S, E> notifyFrom = currentState;
|
||||
currentState = findDeep;
|
||||
if (!isRunning()) {
|
||||
start();
|
||||
}
|
||||
entryToState(findDeep, message, transition, stateMachine);
|
||||
notifyStateChanged(buildStateContext(Stage.STATE_CHANGED, message, null, getRelayStateMachine(), notifyFrom, findDeep));
|
||||
if (!isRunning() && !isComplete()) {
|
||||
start();
|
||||
}
|
||||
}
|
||||
|
||||
if (currentState != null && !nonDeepStatePresent) {
|
||||
|
||||
@@ -177,7 +177,7 @@ public class StateMachinePersistTests extends AbstractStateMachineTests {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testSubsInRegions() throws Exception {
|
||||
public void testSubsInRegions1() throws Exception {
|
||||
context.register(Config51.class, Config52.class);
|
||||
context.refresh();
|
||||
|
||||
@@ -208,6 +208,30 @@ public class StateMachinePersistTests extends AbstractStateMachineTests {
|
||||
assertThat(stateMachine2.getState().getIds(), containsInAnyOrder("S12", "S22", "S221"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testSubsInRegions2() throws Exception {
|
||||
context.register(Config51.class, Config52.class);
|
||||
context.refresh();
|
||||
|
||||
InMemoryStateMachinePersist1 stateMachinePersist = new InMemoryStateMachinePersist1();
|
||||
StateMachinePersister<String, String, String> persister = new DefaultStateMachinePersister<>(stateMachinePersist);
|
||||
|
||||
StateMachine<String, String> stateMachine1 = context.getBean("machine1", StateMachine.class);
|
||||
StateMachine<String, String> stateMachine2 = context.getBean("machine2", StateMachine.class);
|
||||
stateMachine1.start();
|
||||
|
||||
stateMachine1.sendEvent("E1");
|
||||
assertThat(stateMachine1.getState().getIds(), containsInAnyOrder("S12", "S21"));
|
||||
stateMachine1.sendEvent("E2");
|
||||
assertThat(stateMachine1.getState().getIds(), containsInAnyOrder("S12", "S22", "S221"));
|
||||
stateMachine1.sendEvent("E3");
|
||||
assertThat(stateMachine1.getState().getIds(), containsInAnyOrder("S12", "S22", "S222"));
|
||||
persister.persist(stateMachine1, "xxx");
|
||||
stateMachine2 = persister.restore(stateMachine2, "xxx");
|
||||
assertThat(stateMachine2.getState().getIds(), containsInAnyOrder("S12", "S22", "S222"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testHistoryFlatShallow() throws Exception {
|
||||
@@ -553,7 +577,12 @@ public class StateMachinePersistTests extends AbstractStateMachineTests {
|
||||
.withExternal()
|
||||
.source("S21")
|
||||
.target("S22")
|
||||
.event("E2");
|
||||
.event("E2")
|
||||
.and()
|
||||
.withExternal()
|
||||
.source("S221")
|
||||
.target("S222")
|
||||
.event("E3");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user