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:
Janne Valkealahti
2017-07-08 17:34:31 +01:00
parent 38977bef71
commit 8c18dc86de
2 changed files with 55 additions and 14 deletions

View File

@@ -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) {

View File

@@ -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");
}
}