等待多个Akka FSM消息

pki*_*sky 3 asynchronous scala fsm actor akka

我有一个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)
Run Code Online (Sandbox Code Playgroud)

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

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

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

Kon*_*ski 5

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

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

我个人最喜欢的(我们倾向于避免ask一般)将标记请求,Envelope(id, payload)因此响应也可以包含在内Envelope(id, response).如果您决定使用域名术语来简单地打电话给这些信封,那么由您决定.

希望这可以帮助.