等待多个Akka FSM消息

时间:2014-07-21 18:39:46

标签: scala asynchronous akka actor fsm

我有一个Akka FSM actor,它在ReadyState

中收到消息后运行以下伪代码
lookupA ! Wrapper(Lookup("A"))
lookupB ! Wrapper(Lookup("B"))
lookupC ! Wrapper(Lookup("C"))
goto(LookingUpDataState) using DataFound(a = None, b = None, c = None)

然后演员等待响应,可以是FullResult[T](延伸ServiceResult[T])或Empty(延伸ServiceResult[Nothing])。成功的查找结果用于填充DataFound实例的字段,而Empty查找结果会导致记录的错误消息和actor的终止。

我的问题是:如何确定哪个查找失败,以便我可以将失败或回退记录为默认值?我能想到的只是检查发件人的ActorRef(hacky)或为所有邮件添加唯一ID字段(高开销)。

这是使用Ask和Futures解决的一个简单问题。是否存在惯用的Akka解决方案?

1 个答案:

答案 0 :(得分:5)

您可以在这里使用一些模式。您将不得不求助于下面列出的其中一个选项。他们都有一些权衡(无论如何,基准测试都是国王),但我已经按照“坏到好”的顺序列出了它们,#34;

  • 按顺序执行查询,所以发送A,等待A响应,发送B ......但是可怕的 - 就像在不必要的顺序中一样。
  • 使用ask模式,这样你就可以(在内部了解问题是如何工作的)3个演员,他们将完成他们自己的"未来。所以这对发送者也有一些成本,因为它必须启动这些特殊目的的演员(小于普通演员,但仍然)。
  • 是的,您需要以某种方式标记这些消息。因此,您要发送一些ID,并且响应必须包含相同的ID,然后您就知道它的响应A"以及A"等我认为这是推荐的方式。
  • Akka中提供的 contrib 模式称为聚合器,专为此用例而设计,因此您可能需要查看它:http://doc.akka.io/docs/akka/2.3.4/contrib/aggregator.html但是如果您愿意不管它与否都是个人品味的问题。

我个人最喜欢的(我们通常会避免ask)会在Envelope(id, payload)中标记请求,因此响应也可以包含在Envelope(id, response)中。如果您决定使用域名术语来简单地打电话给这些信封或更多信息取决于您。

希望这有帮助。