Fix event defer issues
- Event may get not accepted in some cases while it should be deferred. Check defer again before accept would return false. - Relates to #131
This commit is contained in:
@@ -592,6 +592,13 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
}
|
||||
}
|
||||
}
|
||||
// if we're about to not accept event, check defer again in case
|
||||
// state was changed between original check and now
|
||||
if ((currentState != null && currentState.shouldDefer(message))) {
|
||||
log.info("Current state " + currentState + " deferred event " + message);
|
||||
stateMachineExecutor.queueDeferredEvent(message);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -272,6 +272,7 @@ public class DefaultStateMachineExecutor<S, E> extends LifecycleObjectSupport im
|
||||
State<S,E> currentState = stateMachine.getState();
|
||||
if (queuedEvent != null) {
|
||||
if ((currentState != null && currentState.shouldDefer(queuedEvent))) {
|
||||
log.info("Current state " + currentState + " deferred event " + queuedEvent);
|
||||
queueDeferredEvent(queuedEvent);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -153,6 +153,39 @@ public class EventDeferTests extends AbstractStateMachineTests {
|
||||
assertThat(machine.getState().getIds(), contains("READY"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeferWithSubs2ThreadExecutor() throws Exception {
|
||||
context.register(Config1.class, ExecutorConfig.class);
|
||||
context.refresh();
|
||||
@SuppressWarnings("unchecked")
|
||||
StateMachine<String, String> machine = context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, StateMachine.class);
|
||||
TestListener listener = new TestListener();
|
||||
machine.addStateListener(listener);
|
||||
machine.start();
|
||||
|
||||
assertThat(listener.stateMachineStartedLatch.await(3, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.stateChangedLatch.await(3, TimeUnit.SECONDS), is(true));
|
||||
|
||||
listener.reset(0, 0, 2, 0);
|
||||
machine.sendEvent("E2");
|
||||
machine.sendEvent("E2");
|
||||
|
||||
assertThat(listener.readyStateEnteredLatch.await(3, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.readyStateEnteredCount, is(2));
|
||||
|
||||
assertThat(machine.getState().getIds(), contains("READY"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeferWithSubs2ThreadExecutorSmoke() throws Exception {
|
||||
// smoke above test to see threading issues
|
||||
for (int i = 0; i < 500; i++) {
|
||||
setup();
|
||||
testDeferWithSubs2ThreadExecutor();
|
||||
clean();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubNotDeferOverrideSuperTransition() throws Exception {
|
||||
context.register(Config3.class);
|
||||
|
||||
Reference in New Issue
Block a user