akka.net Хранение сообщений во время определенного состояния актера

akka.net

1003 просмотра

2 ответа

У меня есть актер (человек), который я хочу, чтобы иметь возможность хранить сообщения во время состояния. Проблема в том, что я не уверен, как лучше всего добиться этого.

Допустим, у меня есть несколько команд.

ChangeAddress
ChangePhoneNumber
BeginMove
FinishMove

Пока я нахожусь в середине движения (после запуска BeginMove и перед FinishMove), я хочу запретить обновления Address и PhoneNumber и просто воспроизвести любые события после завершения перемещения. Я использую ReceivePersistentActor, и каждая команда - это отдельный класс.

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

Также в качестве побочного вопроса есть ли хороший шаблон для разбивки количества команд и восстановлений, которые должны быть написаны, поскольку актер должен обрабатывать больше команд / событий?

Автор: Josh Источник Размещён: 08.11.2019 11:29

Ответы (2)


3 плюса

Акка уже имеет это:

http://getakka.net/docs/working-with-actors/Stashing%20Messages

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

В вашем примере вы получите BeginMoveкоманду и перейдете в состояние Moving с помощью вызова Become(Moving). В следующий раз, когда сообщение будет обработано, вы окажетесь в этом новом состоянии. Внутри вашего метода Moving вы должны настроить Receive<ChangeAddress>обработчики сообщений таким образом, чтобы они сохраняли сообщение, а все остальные обработчики имели то поведение, которое вы хотите во время перемещения. В какой-то момент в будущем вам понадобится FinishMoveкоманда, которая вернет ваше поведение к тому, что было до того, как вы начали движение, и отменяет сброс всех сообщений. В этот момент все спрятанные сообщения начнут обрабатываться в исходном состоянии поведения. Это все неблокирует .

void OriginalState()
    {
        Receive<ChangeAddress>(s =>
        {
             // change address logic
        });

        Receive<BeginMove>(msg =>
        {
            Become(Moving);
        }
    }

void Moving()
    {
        Receive<ChangeAddress>(s =>
        {
            Stash.Stash();
        });

        Receive<FinishMove>(msg =>
        {
            Become(OriginalState);
            Stash.UnstashAll();
        }
    }

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

Один из способов разобраться в этом - делегировать поведение дочерним актерам, если это уместно, но на этом этапе это становится проблемой проектирования.

Автор: tomliversidge Размещён: 21.08.2016 05:46

0 плюса

обо всем по порядку: пока нет вызовов PipeTo () - ничего не изменится.

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

Чтобы избежать прерывания при обработке длинного звонка (например, с использованием db) - я укладываю стека моего актера - пожалуйста, посмотрите пример с получением актера. Это позволяет:

  1. прекратить обработку входящих
  2. предотвращает остановку методом диспетчером (тайм-аут)
  3. избегает использования тайника, так как он не нужен

    public class ProcessActor : ReceiveActor{
    
     public ProcessActor() {
    
        Receive < ChangeAddress > (
            message =  > {
                BecomeStacked(ProcessingOrDoNothing);
                //{do the job here}
                UnbecomeStacked();
            });
     }
    
      public void ProcessingOrDoNothing(){}
    
    }
    
Автор: profesor79 Размещён: 22.08.2016 08:36
Вопросы из категории :
32x32