我正在尝试为现金接收机器建模。
我的StateMachine配置如下。我省略了一些不重要的状态和事件。
@Override
public void configure(StateMachineStateConfigurer<States, Events> states) throws Exception {
states
.withStates()
.initial(States.INIT, initAction())
.state(States.CONNECTED)
.and()
.withStates()
.parent(States.CONNECTED)
.initial(States.READY)
.state(States.READY)
.fork(States.ACCEPTING_CASH_FORK)
.state(States.ACCEPTING_CASH)
.join(States.ACCEPTING_CASH_JOIN)
.choice(States.PROCESSING_CASH)
.state(States.PRINTING_RECEIPT, printingReceiptAction(), null)
.and()
.withStates()
.parent(States.ACCEPTING_CASH)
.initial(States.BNR_CASH_IN_START)
.state(States.BNR_CASH_IN_END)
.end(States.BNR_CASH_IN_EXIT)
.and()
.withStates()
.parent(States.ACCEPTING_CASH)
.initial(States.CNR_CASH_IN_START)
.state(States.CNR_CASH_IN_END)
.end(States.CNR_CASH_IN_EXIT)
.and();
}
@Override
public void configure(StateMachineTransitionConfigurer<States, Events> transitions) throws Exception {
transitions
.withExternal()
.source(States.INIT).target(States.CONNECTED)
.and()
.withExternal()
.source(States.READY)
.target(States.ACCEPTING_CASH_FORK)
.event(Events.ACCEPT_CASH)
.and()
.withFork()
.source(States.ACCEPTING_CASH_FORK)
.target(States.BNR_CASH_IN_START).target(States.CNR_CASH_IN_START)
.and()
.withExternal()
.source(States.BNR_CASH_IN_END)
.target(States.BNR_CASH_IN_EXIT)
.event(Events.BNR_CASH_IN_END_COMPLETED)
.and()
.withExternal()
.source(States.CNR_CASH_IN_END)
.target(States.CNR_CASH_IN_EXIT)
.event(Events.CNR_CASH_IN_END_COMPLETED)
.and()
.withJoin()
.source(States.BNR_CASH_IN_EXIT).source(States.CNR_CASH_IN_EXIT).target(States.ACCEPTING_CASH_JOIN)
.and()
.withExternal()
.source(States.ACCEPTING_CASH_JOIN)
.target(States.PROCESSING_CASH)
.and()
.withChoice()
.source(States.PROCESSING_CASH)
.first(States.DISPENSING_CASH_FORK, dispensingCashGuard(), dispensingCashAction())
.last(States.PRINTING_RECEIPT)
.and();
}
我还配置了一个监听器以进行调试。
@Bean
public StateMachineListener<States, Events> listener() {
return new StateMachineListenerAdapter<States, Events>() {
@Override
public void stateChanged(State<States, Events> from, State<States, Events> to) {
log.info("State change from " + (from != null ? from.getId() : from) + " to " + to.getId());
}
@Override
public void stateMachineStarted(StateMachine<States, Events> stateMachine) {
log.info("StateMachine uuid " + stateMachine.getUuid() + " state " + stateMachine.getState().getId());
}
@Override
public void transition(Transition<States, Events> transition) {
Trigger<States, Events> trigger = transition.getTrigger();
State<States, Events> source = transition.getSource();
State<States, Events> target = transition.getTarget();
log.info("Transition trigger " + (trigger != null ? trigger.getEvent() : trigger) +
" source " + (source != null ? source.getId() : source) +
" target " + (target != null ? target.getId() : target) + " kind " + transition.getKind());
}
};
}
问题出在 ACCEPTING_CASH_JOIN 加入当达到2个状态 BNR_CASH_IN_EXIT 和 CNR_CASH_IN_EXIT 时,该状态机应该处于哪个状态。但是在日志中,statemachine没有达到它。
2017-06-30 19:59:06.891 INFO 3776 --- [ Thread-9] k.d.c.config.StateMachineConfiguration : StateMachine uuid 52e51cf0-06f0-4efa-8d05-1717bf869239 state CONNECTED
2017-06-30 19:59:06.891 INFO 3776 --- [ Thread-9] k.d.c.config.StateMachineConfiguration : State change from null to CNR_CASH_IN_END
2017-06-30 19:59:06.892 INFO 3776 --- [ Thread-8] k.d.c.config.StateMachineConfiguration : Transition trigger CNR_CASH_IN_END_COMPLETED source CNR_CASH_IN_END target CNR_CASH_IN_EXIT kind EXTERNAL
2017-06-30 19:59:06.892 INFO 3776 --- [ Thread-8] k.d.c.config.StateMachineConfiguration : State change from CNR_CASH_IN_END to CNR_CASH_IN_EXIT
2017-06-30 19:59:06.924 INFO 3776 --- [ Thread-8] k.d.c.config.StateMachineConfiguration : StateMachine uuid 52e51cf0-06f0-4efa-8d05-1717bf869239 state CONNECTED
2017-06-30 19:59:06.924 INFO 3776 --- [ Thread-8] k.d.c.config.StateMachineConfiguration : State change from null to BNR_CASH_IN_END
2017-06-30 19:59:07.146 INFO 3776 --- [ Thread-8] k.d.c.config.StateMachineConfiguration : Transition trigger BNR_CASH_IN_END_COMPLETED source BNR_CASH_IN_END target BNR_CASH_IN_EXIT kind EXTERNAL
2017-06-30 19:59:07.146 INFO 3776 --- [ Thread-8] k.d.c.config.StateMachineConfiguration : State change from BNR_CASH_IN_END to BNR_CASH_IN_EXIT
2017-06-30 19:59:27.239 DEBUG 3776 --- [ XNIO-2 task-4] k.d.c.w.rest.StateMachineQueryResource : [CONNECTED, ACCEPTING_CASH, BNR_CASH_IN_EXIT, CNR_CASH_IN_EXIT]
最后一行是我通过在statemachine stateMachine.getState()上调用方法来检查当前状态的方法.getIds()
答案 0 :(得分:0)
你介意分开尝试两件事吗
我还没有检查是否有针对此特定用例的测试来验证它是否应该起作用。理论是终端状态不能具有传出转换,因此连接可能不起作用。