如何在Actor模型框架(例如akka.net)中执行非幂等动作(发送电子邮件)?

时间:2018-11-16 00:15:47

标签: akka actor akka.net

我正在研究使用参与者模型框架(具有akka.net持久性的akka​​.net,但我正在寻找一个通用的案例答案)来构建“小部件订单处理工作流”。

相当标准:

  1. 客户订单小部件
  2. 付款已处理
  3. 电子邮件确认已发送给客户
  4. 发送选择列表消息到仓库
  5. 仓库发送回“小部件已发货”消息
  6. 发送“您的商品已寄出”电子邮件给客户

现在让我们说在4到5之间发生了服务器部署/重启。这将导致演员补液(假设尚无快照)。这意味着我们将再次处理付款,然后重新发送下订单的电子邮件。但是事实证明,我们的客户不喜欢这种“功能”!

在使用参与者模型框架时如何防止非幂等动作再次发生?

我曾考虑过要单独存储“为订单数据库表处理的付款”;但这感觉就像我在挑战框架/范式,我想知道是否有“适当”的方式来做这种事情!

2 个答案:

答案 0 :(得分:0)

好吧,事实证明这很简单。

使用akka.net持久性,在系统还原后,将重播消息。可以通过(重新)处理这些消息来重新创建正确的状态。

但是有一个IsRestoring属性,可以检查该属性是否是第一个或后续处理。大概其他的参与者模型框架也有相似之处。

所以您可以执行以下操作:

private void ProcessPayment (Order message)
{
    if(!this.IsRestoring){
        //Perform non-idempotent payment process
    }
}

答案 1 :(得分:-1)

要构建一个强大的工作流处理器,您必须将工作流过程的所有数据存储在一个永久存储器中。

您可以使用数据库,像Kafka这样的消息传递系统,也可以使用现成的工作流管理软件。

由于您已经在使用Akka,因此Akka Persistence也可以作为一种选择。

更新

构建一个在出现系统故障和重新启动的情况下仍能正常正常工作的系统是一项艰巨的任务,比开发参与者框架要复杂得多。也就是说,您不能仅仅采用任何actor框架并为其添加容错功能。