Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transition with the same event in multiple regions #1111

Open
Balint-Ivanics-KUKA opened this issue Aug 25, 2023 · 2 comments
Open

Transition with the same event in multiple regions #1111

Balint-Ivanics-KUKA opened this issue Aug 25, 2023 · 2 comments
Labels
status/need-triage Team needs to triage and take a first look

Comments

@Balint-Ivanics-KUKA
Copy link

Hi,

Multiple regions of the same state machine using the same event for transition don't react as I would expect based on the docs.
"Whether you send one event or multiple events, result is always a sequence of results. This is so because in a presence multiple reqions, results will come back from multiple machines in those regions. This is shown with method sendEventCollect which gives a list of results." To me this suggested that multiple regions can accept the event but it looks like that is not the case.

If I have the following state machine:

    public void configure(StateMachineStateConfigurer<MyStateMachineState, MyStateMachineEvent> states)
            throws Exception
    {
        states
                .withStates()
                .initial(BasicState.ROOT)
                .and()
                .withStates()
                .parent(BasicState.ROOT)
                .region("region1")
                .initial(BasicState.CHILD11)
                .state(BasicState.CHILD12)
                .and()
                .withStates()
                .parent(BasicState.ROOT)
                .region("region2")
                .initial(BasicState.CHILD21)
                .state(BasicState.CHILD22);
    }

    public void configure(StateMachineTransitionConfigurer<MyStateMachineState, MyStateMachineEvent> transitions)
            throws Exception
    {
        transitions
                .withExternal().source(BasicState.CHILD11).target(BasicState.CHILD12).event(BasicEvent.EVENT)
                .and()
                .withExternal().source(BasicState.CHILD21).target(BasicState.CHILD22).event(BasicEvent.EVENT);
    }

then if I send a BasicEvent.EVENT only one of the regions will transition. I would have expected both to transition.

Is this the intended behavior?

Thanks

@github-actions github-actions bot added the status/need-triage Team needs to triage and take a first look label Aug 25, 2023
@manhnt217
Copy link

I'm new to Spring state machine. I'm experiencing the same behaviour.

@wlfbck
Copy link

wlfbck commented Sep 4, 2024

I'm seeing something similar here. I can actually reliably trigger either both regions transitioning or only one by adding/removing an action to that transition.
The code is nothing special, simply a state machine with two regions (order and ncprogram) which listen to the same event (also named order). Ignore the second event named ncprogram, it is not relevant to the problem. I'm adding an actionFunction() to the order transition to get the second log.

Log without action (this is the expected output):

10:38:15,694 INFO  ContextGenerator            [] - Receiving event order
10:38:15,713 INFO  StateMachineLogger          [] - transition 'order-canExist to order-exists' triggered by event 'order'
10:38:15,715 INFO  StateMachineLogger          [] - stateChanged from 'order-canExist' to 'order-exists'
10:38:15,717 INFO  StateMachineLogger          [] - transition 'ncprogram-cannotExist to ncprogram-canExist' triggered by event 'order'
10:38:15,717 INFO  StateMachineLogger          [] - stateChanged from 'ncprogram-cannotExist' to 'ncprogram-canExist'
10:38:15,717 INFO  ContextGenerator            [] - Receiving event ncprogram
10:38:15,718 INFO  StateMachineLogger          [] - eventNotAccepted: ncprogram
10:38:15,719 INFO  StateMachineLogger          [] - transition 'ncprogram-canExist to ncprogram-exists' triggered by event 'ncprogram'
10:38:15,719 INFO  StateMachineLogger          [] - stateChanged from 'ncprogram-canExist' to 'ncprogram-exists'
10:38:15,720 INFO  StateMachineLogger          [] - eventNotAccepted: ncprogram

Log with action attached to transition (ncprogram region is not transitioning at all):

10:38:35,423 INFO  ContextGenerator            [] - Receiving event order
10:38:35,446 INFO  StateMachineLogger          [] - transition 'order-canExist to order-exists' triggered by event 'order'
10:38:35,448 INFO  StateMachineLogger          [] - stateChanged from 'order-canExist' to 'order-exists'
10:38:35,456 INFO  StateMachineLogger          [] - eventNotAccepted: order
10:38:35,457 INFO  StateMachineLogger          [] - eventNotAccepted: order
10:38:35,457 INFO  ContextGenerator            [] - Receiving event ncprogram
10:38:35,457 INFO  StateMachineLogger          [] - eventNotAccepted: ncprogram
10:38:35,457 INFO  StateMachineLogger          [] - eventNotAccepted: ncprogram
10:38:35,457 INFO  StateMachineLogger          [] - eventNotAccepted: ncprogram
10:38:35,458 INFO  StateMachineLogger          [] - eventNotAccepted: ncprogram
10:38:35,458 INFO  StateMachineLogger          [] - eventNotAccepted: ncprogram

edit:
@jvalkeal I found the issue, and imho is something that needs changing. When exception occurs during the action, it is completely invisible to the user (even when having a StateMachineListener which prints everything) that this happens. Sure, it might be somewhere inside the Flux stuff, but the whole documentation always does sendEvent(..).subscribe() which means you never actually get to see/use StateMachineEventResult.
So another sendEvent message would be nice, which does the subscribe() for you and returns List<StateMachineEventResult<..>> . A shorthand for stateMachine.sendEvent(Mono.just(message)).collectList().block(); if you will. Also the documentation might need updating in that regard, as someone who has never used Flux before this was pretty intransparent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status/need-triage Team needs to triage and take a first look
Projects
None yet
Development

No branches or pull requests

3 participants