Akka экземпляры конечного автомата

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

Запрос здесь - это имя приложения, которое необходимо развернуть вместе с приложением, от которого оно зависит:

Request for application A -> A is in a QUEUED state
Discover A's dependency B -> B is in a QUEUED state
B is being processed -> B is in a PROCESSING STATE
A is being processed -> A is in a PROCESSING STATE
B is processed -> B is in a DONE state
A is processed -> A is in a DONE state

Для этого я инициализирую конечный автомат во время открытия. Так A's FSM создается, когда приходит запрос, BFSM инициализируется, когда B обнаружен у одного из актеров.

Я инициализирую и передаю экземпляр FSM всем актерам, и в то же время tell FSM об операциях, выполняемых с данными, чтобы конечный автомат перешел в правильное состояние?

Вот соответствующая часть конечного автомата:

when(QUEUED, matchEvent(requestAccepted.class, MyApp.class,
    (requestAccepted, service) -> 
    goTo(PROCESSING).replying(PROCESSING)));

when(PROCESSING, matchEvent(completed.class, MyApp.class,
    (completed, service) -> goTo(DONE).replying(DONE)));

// During transitions, save states in the database.
onTransition(matchState(PROCESSING, DONE, () -> {
  nextStateData().setServiceStatus(DONE);
  databaseWriter.tell(nextStateData(), getSelf());

А вот пример одного из участников, обрабатывающих запрос:

ProcessingActor extends AbstractActor {

    @Override
      public void onReceive(Object message) throws Throwable {
        if (message instanceof processApplication) {
         // process the app
         // Initialize FSM for the Application
         FSM myFSM = Props.create(MYFSM.class);
         myFSM.tell( new completed(processApplication.app)
    }

Это правильный способ инициализации конечного автомата и его использования? Или если инициализация произойдет в конструкторе ProcessingActor? Но в этом случае не было бы одного конечного автомата на приложение (данные).

0 ответов

Хотя описание состояний и переходов в ОП довольно неоднозначно, можно рассмотреть статус выбранной реализации, ее последствия и последствия альтернатив.

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

В своей нынешней форме данная реализация является единственным AbstractFSM на запрос, о котором я знаю, на самом деле с еще одним конечным автоматом в нисходящем направлении, который в таком случае больше не может вызываться "на запрос" и, вероятно, его можно было бы избежать. Это выглядит примерно так:

"Актер на запрос" изначально, кажется, возник в этой дискуссии, которая дала толчок этому блогу, а чуть позже даже иногда заявляла о названии шаблона. Похоже, что отчасти это было мотивировано копированием одной из функций фреймворка Spray, своего рода предшественника Akka http.

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

Подход чаще всего представлен в сочетании с AbstractFSM и его разновидностями, однако, является один субъект FSM, который буферизует входящие сообщения, используя whenUnhandledспособ накапливать их по умолчанию, независимо от того, что текущее состояние (например, Akka в действии, глава "Конечные автоматы и агентов" или Lightbend группирователя например). Я не могу создать резервную копию утверждения ссылкой, но похоже, что AbstractFSM больше предназначен для моделирования состояний актора, который имеет дело с несколькими запросами, а не для запроса, который проходит несколько этапов. В отношении OP этот подход означал бы, чтоProcessingActor сам может расширить AbstractFSM.

public class ProcessingActor extends AbstractFSM<sample.so.State, RequestQueue> {
{
    startWith(Idle, new RequestQueue());

    when(Idle, /* matchEvent(EventType, DataType, Action) */
            matchEvent(
                    Request.class,
                    RequestQueue.class,
                    (request, queue) -> goTo(Processing).using(queue.push(request)));
    /* more state-matchers */

    whenUnhandled(
            matchEvent(
                    Request.class,
                    RequestQueue.class,
                    (request, qeue) -> stay().using(qeue.push(request)));

    initialize();
}

Получение чего-то подобного для части "запроса", где записи в базу данных больше не представлены состояниями, а не действиями входа и выхода состояния. Обратите внимание, что всеwhenUnhandled ветка не отображается на диаграмме, поскольку не связана с изменением состояния.

Не вдаваясь в подробности взвешивания (расплывчатых) требований в отношении выбранной реализации, AbstractFSMкажется довольно неуклюжим механизмом для регистрации последовательности статуса каждого запроса к базе данных. В документации по Akka версии 2.4 представлен конечный автомат без использования AbstractFsm и обсуждается возможность различать сначала события, а затем состояния или наоборот. вAbstractFSM-DSL вы обязаны различать состояния до событий (и данных). Можно даже поспорить с некоторым оправданием, чтобы вообще воздерживаться от akka FSM.

Более легкий подход к построению FSM использует " стать / не стать", хорошая презентация здесь,AbstractFSMобсуждение vs. стать / непостоянным можно найти здесь. Более близкая визуальная близость к бизнес-правилам дает главный аргумент в пользу первого.

Вступление в более скользкую местность оценки использования AbstractFSM для задачи на had. Я думаю, что кое-что можно сказать, учитывая, что чтение требований примерно нормально.

Состояния образуют линейную цепочку, поэтому две "AbstractFSM-per-request" могут быть заменены другими структурами для каждого запроса:

  • единая цепочка субъектов, каждый из которых представляет одно состояние

  • один субъект, отправляющий события самому себе, один тип события на шаг, показанный выше, отправляющий сообщения автору базы данных в каждой точке. Может быть, и перечисления будет достаточно.

Учитывая это, привлекательность этих версий может возрасти: поскольку данная реализация использует (по крайней мере) один автомат на запрос, возникает вопрос, как происходит переход QUEUED->PROCESSING происходит (или discovery processing -> discovery done в этом отношении), и что QUEUEDотносится к техническому уровню. Элементы никогда не находятся в очереди, всегда в эксклюзивном актере (с другой стороны, состояние QUEUED будет более очевидным в одной ФОМ подход, который на самом деле использует очередь, но тогда государство не относится к актеру, но предмет, которым управляет актер). Не очевидно, какое внешнее событие должно вызвать этот переход. Akka FSM предназначен для описания детерминированного конечного автомата (см. Также это, приводя тот же аргумент по противоположным причинам), но если этот переход не запускается внешним событием, конечный автомат должен стать недетерминированным и запускать свои собственные эпсилон-переходы.~ переходы, не вызванные каким-либо вводом. Довольно сложная структура, возможно, реализованная как-то так:

onTransition(
    matchState(Initial, Queued, () -> {                    
        getSelf().tell(new Epsilon(), getSelf());
    }));
Другие вопросы по тегам