Как обрабатывать события, которые не были обработаны конечным автоматом - PullRequest
0 голосов
/ 26 декабря 2018

Допустим, у нас есть следующая конфигурация конечного автомата:

transitions.withExternal()
    .source(FIRST)
    .target(SECOND)
    .event(STEP_EVENT)

    .and()

    .source(SECOND)
    .target(EXIT)
    .event(EXIT_EVENT)

Список событий: STEP_EVENT, EXIT_EVENT, UNUSED_EVENT

stateMachine.init(); 
// FIRST state

stateMachine.sendEvent(STEP_EVENT); 
/* state moves to SECOND 
because there is a transition with current state as a source 
and STEP_EVENT as transition event */

stateMachine.sendEvent(UNUSED_EVENT); 
/* no state change. 
This will trigger "eventNotAccepted(Message<Events> event)" 
in state machine listener, 
because UNUSED_EVENT is never mentioned in SM config */

stateMachine.sendEvent(STEP_EVENT); 
/* nothing will happen!!! 
No state change, as there is no transition 
which has current state (SECOND) as source 
and STEP_EVENT as transition event, 
and no eventNotAccepted call. 
But I need it, I want to fail here! */

stateMachine.sendEvent(EXIT_EVENT); 
// state will move to EXIT

Проблема в том, что когда я отправлял событиекоторая является частью конфигурации, но не применима для текущего состояния, ничего не происходит.

Я не знаю, не изменилось ли состояние из-за защиты или потому что нет перехода с текущим состоянием и моим событием.

Есть ли способ обработать такие случаи?

Ответы [ 2 ]

0 голосов
/ 17 февраля 2019

Решено!Как это часто бывает, решение было слишком простым для меня, чтобы наблюдать его :(. Поэтому метод, который отправляет событие в SM, имеет логический параметр возврата. И если событие было обработано и обработано, он возвращает true и false в противном случае.

Вот и все - просто проверьте возвращаемое значение!

0 голосов
/ 15 февраля 2019

Для регистрации событий, которые не применимы для вашего текущего состояния, вы можете использовать прослушиватель StateMachine.Существует метод, вызываемый каждый раз, когда в конечном автомате передается событие, которое не удовлетворяет определенным переходам и событиям.

В конфигурации конечного автомата необходимо переопределить:

public void configure(StateMachineConfigurationConfigurer<State, Event> config) {
  config.withConfiguration()
     .listener(customListener());
}

и реализовать свой собственный Слушатель - самый простой способ - использовать StateMachineListenerAdapter и переопределить метод eventNotAccepted(Message event):

private StateMachineListenerAdapter<State, Event> customListener() {
  return new StateMachineEventListenerAdapter<State, Event>() {

    @Override
    public void eventNotAccepted(Message event) {
      //LOG which event was not accepted etc.
    }
  }
}

Для регистрации результатов охранников- используйте сообщения журнала в самих охранниках.

Если вы хотите раскрыть причину вне охранников, вы можете создать пару ключ-значение и использовать расширенный контекст StateMachine для записи имени охранника и причины, по которойСобытие было отклонено.Контекст может использоваться для создания пользовательского исключения или передачи кода вызывающей стороны о том, что произошло.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...