Open
Description
I am exploring Spring state machine and was testing a scenario where state machine would run to completion after resetting from a specific state but it runs in an infinite loop. The below code is enough to reproduce the issue.
Basically, there is one state machine that on event e1
will transition from s1
to s2
and then it will transition to s3
and s4
(triggerless transition). I want to make this state machine run from s2
to completion, but it ends up in a infinite loop, executing (and printing) s3 action
@Test
public void loop() throws Exception {
var sm = buildMachine();
Flux.fromIterable(sm.getStateMachineAccessor().withAllRegions())
.flatMap(region -> region.resetStateMachineReactively(new DefaultStateMachineContext<>("s2", null, null, null)))
.subscribe();
sm.startReactively().block();
sm.sendEvent(Mono.just(MessageBuilder
.withPayload("e1")
.build())).subscribe();
}
@SneakyThrows
StateMachine<String, String> buildMachine() {
StateMachineBuilder.Builder<String, String> builder = StateMachineBuilder.builder();
builder.configureConfiguration()
.withConfiguration()
.autoStartup(false);
builder.configureStates()
.withStates()
.initial("s1")
.end("s4")
.states(Set.of("s1", "s2", "s3", "s4"));
// @formatter:off
builder.configureTransitions()
.withExternal()
.source("s1")
.event("e1")
.target("s2")
.action((p) -> logger.info("s2 action"), (p) -> logger.info("s2 action failed"))
.and()
.withExternal()
.source("s2")
.target("s3")
.action((p) -> logger.info("s3 action"))
.and()
.withExternal()
.source("s3")
.target("s4");
// @formatter:on
return builder.build();
}
What am I missing here?
Note: posted on StackOverflow too