Beh01der / EasyFlow

EasyFlow - Simple and lightweight Finite State Machine for Java
http://datasymphony.com.au/open-source/easyflow
Apache License 2.0
442 stars 87 forks source link

Handlers fired multiple times for same transition #14

Open adamwasila opened 10 years ago

adamwasila commented 10 years ago

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.

night2tl commented 8 years ago

Is this issue resolved already?