-
Notifications
You must be signed in to change notification settings - Fork 87
Description
I'm trying to implement simple FSM to manage UI state in Android application. Here is a problem I found (isolated to an abstract example):
FSM definition (pseudo code):
State { A, B, C }
Event { next }
fsm = from(State.A).transit(
on(Event.next).to(State.B).transit(
on(Event.next).to(State.C).transit(
on(Event.next).to(State.A)
)
)
);
fsm.executor(new UIThreadExecutor()); // same as in android ATM example
Handler on "whenEnter":
mFlow.whenEnter(new StateHandler<FlowContext>() {
@Override
public void call(StateEnum state, FlowContext context) throws Exception {
println("entering: " + state);
Thread.sleep(200); // delay handler execution, so that issue become repeatable
}
});
Now, last but not least, following code is executed on some event (eg. button press):
mContext.trigger(Event.next);
mContext.trigger(Event.next);
mContext.trigger(Event.next);
Expected result:
entering: A
entering: B
entering: C
entering: A
Observed result:
entering: A
entering: B
entering: B
entering: B
My understanding of what causes an issue here:
After looking briefly into code I see that triggering is implemented in a strange way by splitting it to two runnables: first, handlers are called in separate executor task, but then another executor task is added to do actual state switching (setCurrentState method). So, as a matter of luck, if second task (state change) is interleaved with another trigger, we may observe handlers being called twice for same transition.