Весной государственная машина застряла в состоянии соединения
Я пытаюсь смоделировать машину для приема наличных.
Моя конфигурация 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 ()
1 ответ
Не могли бы вы попробовать две вещи отдельно
- Измените эти конечные состояния на нормальные состояния.
- Вместо присоединения по конечным состояниям присоедините их по родительскому состоянию (ACCEPTING_CASH).
Я еще не проверял, есть ли тесты для этого конкретного варианта использования, чтобы проверить, должен ли он работать или нет. Теория заключается в том, что конечные состояния не могут иметь исходящие переходы, поэтому объединение может не работать.