Transition Handlers defined using @OnTransition stop working when statemachine is rehydrated using new StateMachineContext
Asked Answered
I

1

1

In the following sample code, I created a state machine and rehydrated it with the state of my choice. However, when I send events, the handlers defined with @OnTransition do not run.

If I comment method-call to #rehydrateState, then the handlers work appropriately. Why is this happening?

Also: if I replace the line

var sm = factory.getStateMachine("Machine1"); with 
var sm = factory.getStateMachine("");

Then all handlers run fine. Why is that the case?

@Configuration
@EnableStateMachineFactory
public class Config extends StateMachineConfigurerAdapter<String, String> {
    @Override
    public void configure(StateMachineStateConfigurer<String, String> states)
            throws Exception {
        var allStates = new HashSet<String>();
        allStates.add("UNPAID");
        allStates.add("WAITING_FOR_RECEIVE");
        allStates.add("DONE");
        states
                .withStates()
                .initial("UNPAID")
                .states(allStates);
    }

    
        @Override
        public void configure(StateMachineTransitionConfigurer<String, String> transitions)
                throws Exception {
            transitions
                    .withExternal()
                    .source("UNPAID").target("WAITING_FOR_RECEIVE")
                    .event("PAY")
                    .and()
                    .withExternal()
                    .source("WAITING_FOR_RECEIVE").target("DONE")
                    .event("RECEIVE")
                    .and()
                    .withExternal()
                    .source("WAITING_FOR_RECEIVE").target("WAITING_FOR_RECEIVE")
                    .event("SELF");
        }
    
        @Override
        public void configure(StateMachineConfigurationConfigurer<String, String> config)
                throws Exception {
            config
                    .withConfiguration()
                    .autoStartup(true);
        }
        
        @WithStateMachine
        static class Action {
            @OnTransition(target = "UNPAID")
            public void create() {
                System.out.println("UNPAID");
            }
    
            @OnTransition(source = "UNPAID", target = "WAITING_FOR_RECEIVE")
            public void pay() {
                System.out.println("WAITING_FOR_RECEIVE");
            }
    
            @OnTransition(source = "WAITING_FOR_RECEIVE", target = "WAITING_FOR_RECEIVE")
            public void self() {
                System.out.println("self works too");
            }
    
            @OnTransition(source = "WAITING_FOR_RECEIVE", target = "DONE")
            public void receive() {
                System.out.println("DONE");
            }
        }
    }
    
    public class Main implements CommandLineRunner {
        public static void main(String[] args) {
            SpringApplication.run(Main.class, args);
        }
    
        @Autowired
        StateMachineFactory factory;
    
        @Override
        public void run(String... args) throws Exception {
            var sm = factory.getStateMachine("Machine1");
            sm.stopReactively().block();
            rehydrateState(sm, sm.getExtendedState(), "WAITING_FOR_RECEIVE");
            sm.startReactively().block();
            sm.sendEvent("PAY");
            sm.sendEvent("SELF");
        }
    
        void rehydrateState(StateMachine<String, String> sm, ExtendedState extendedState, String status) {
            sm.getStateMachineAccessor().doWithAllRegions(sma -> {
                sma.resetStateMachineReactively(new DefaultStateMachineContext<>(status, null, null, extendedState)).block();
            });
        }
    }
Invocate answered 25/9, 2022 at 14:39 Comment(0)
I
1

Replaced #resetStateMachineReactively method call by passing machine Id and all handlers started to work.

sma.resetStateMachineReactively(new DefaultStateMachineContext<>(status, null, null, extendedState, null, sm.getId())).block();
Invocate answered 25/9, 2022 at 15:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.