akka.net在角色

时间:2016-08-20 15:23:10

标签: akka.net

我有一个演员(人),我希望能够在状态期间存储消息。问题是我不确定如何最好地实现这一目标。

假设我有一些命令。

ChangeAddress
ChangePhoneNumber
BeginMove
FinishMove

当我处于移动过程中(在BeginMove开始之后和FinishMove之前)我想阻止更新Address和PhoneNumber,并在移动完成后重放任何事件。我使用的是ReceivePersistentActor,每个命令都是不同的类。

现在我正在考虑演员的状态标志,但是成为/不成功的功能会更自然,但却无法看到如何将它应用于不同的命令。

另外,作为一个侧面问题,有一个很好的模式可以分解必须写入的命令和恢复数量,因为演员需要处理更多的命令/事件吗?

2 个答案:

答案 0 :(得分:3)

Akka已经内置了这个:

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

您可以在收到消息时将消息存储在一个状态,然后在准备好转换到相关状态时解除消息。然后,隐藏的邮件将转到邮箱的前面进行处理。

在您的示例中,您将收到BeginMove命令并通过调用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();
        }
    }

有关如何配置状态以处理邮件类型的更多示例代码,请参阅switchable behaviours

解决问题的一种方法是在适当的时候将行为委托给儿童演员,但在那个阶段它变成了更多的设计问题。

答案 1 :(得分:0)

首先要做的事情是:只要没有PipeTo()调用 - 就没有什么可以改变的。

每个参与者一次处理一条消息,因此当它获得一个请求列表时,它们将按顺序逐个接收顺序处理。

为了避免在处理长时间运行的呼叫时出现中断(比如使用数据库) - 我正在堆叠我的演员 - 请参阅接收演员的示例。这允许:

  1. 停止处理收件箱
  2. 通过调度程序(超时)阻止停止方法
  3. 避免使用藏匿,因为它不需要

    public class ProcessActor : ReceiveActor{
    
     public ProcessActor() {
    
        Receive < ChangeAddress > (
            message =  > {
                BecomeStacked(ProcessingOrDoNothing);
                //{do the job here}
                UnbecomeStacked();
            });
     }
    
      public void ProcessingOrDoNothing(){}
    
    }