在Akka中建议的命令验证方法是什么?

时间:2018-05-19 09:12:23

标签: akka cqrs akka.net

假设我有以下情况。有一个UserActor。除了像Id,FirstName,LastName这样的简单属性之外,用户内部状态还包含一个CategoryId,它表示用户对特定类别的依从性。类别本身是一个单独的域实体,它拥有自己的属性。要执行赋值用户到特定类别的操作,我必须确保特定类别实际存在。处理这种保证系统一致性的场景的正确方法是什么?

我正在考虑两种解决方案,但我不确定哪种解决方案比另一种解决方案更差。

  1. 忽略规则“告诉不要问”,并使用Ask协议查询CategoriesActor以确定是否存在具有指定ID的类别?
  2. 生成某种辅助actor(ValidatorActor),它执行所有必要的验证并将结果回复给UserActor。与此同时,UserActor将其状态更改为“等待命令结果”,并将所有传入的消息堆叠起来,直到正确的命令验证结果到达。
  3. 第一种解决方案否认了我所相信的一切。第二部分在阶级/演员扩散方面的规模并不太好。此外,如果UserActor是持久性FSM,我不知道如何从这个“等待命令验证结果”回归。 FSM没有不成比例。

    我相信如果你将Akka与CQRS / ES方法结合使用,你应该处理这类问题。你是怎么解决的?我读了几本关于阿卡的书,但没有找到任何自以为是的方法。这很奇怪,因为在我看来,这是一个基本的用例。

    我真的很感激任何提示。

2 个答案:

答案 0 :(得分:1)

您正在尝试防止可能随时发生的无效系统状态。在用户遵守该类别后,可以随时删除该类别。

在分布式环境中,阻止可伸缩系统进入无效状态是不可能的。相反,您应该关注系统如何从无效状态中恢复。在这种特殊情况下,你应该考虑当一个类别被删除并且有一些用户遵守它时,会发生什么(而不是!)。也许你告诉他们X类不再存在或只是悄悄地删除他们的成员?你的商界人士应该告诉你。

您可以在用户执行命令之前检查类别的存在,但仅作为优化,以限制滥用您的数据的滥用用户,而不是在系统架构的核心。

  

忽略规则“告诉不要问”,并使用Ask协议查询CategoriesActor以确定是否存在具有指定Id的类别?

此规则不适用于此处,但适用于您向Actor询问某些内容然后告诉相同的 Actor根据其告诉您的内容执行某些操作的情况。

P.S。我假设您有一个分布式系统,因为您选择使用Actor模型。

答案 1 :(得分:0)

我略微弯曲了"告诉,不要问"的规则。 Akka.net的Receive和Command方法有一个名为shouldHandle的可选谓词。我做ask,但在shouldHandle方法中执行了Sender.Tell()。如果谓词的结果为false,则不会运行您指定的操作。

示例代码:

public MyActor
{
    Command<Object>(cmd => HandleObject(cmd), cmd => ValidateObject(cmd));
}

private bool ValidateObject(Object cmd)
{
    // Perform validation as necessary... isValid could be anything but needs to be set
    if(isValid)
    {
        Sender.Tell(true);
        return true;
    }
    else
    {
        Sender.Tell(false);
        return false;
    }
}

private void HandleObject(Object cmd)
{
    // Handle command
}

在上面的代码中,HandleObject将永远不会运行,除非ValidateObject返回true。此模式适用于asktell。我执行ask的唯一原因是因为我需要通知用户该命令是否未通过验证...否则我会使用tell而不必担心执行Sender.Tell