我有一个 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]
) or Empty
(延伸ServiceResult[Nothing]
)。成功的查找结果用于填充 DataFound 实例的字段,空查找结果会导致记录错误消息并终止执行者。
我的问题是:如何确定哪个查找失败,以便我可以记录失败或回退到默认值?我能想到的就是检查发送者的 ActorRef(hacky)或向所有消息添加唯一的 ID 字段(高开销)。
这是一个使用 Ask 和 Futures 可以解决的简单问题。是否存在惯用的 Akka 解决方案?
您可以在这里使用一些模式。您将不得不求助于下面列出的这些选项之一。它们都有一些权衡(无论如何基准测试是王道),但我按照“坏到好”的顺序列出了它们,
- 按顺序执行查询,因此发送 A,等待 A 响应,发送 B ...但这就是horrible- 就像不必要的顺序一样。
- use the
ask
模式,所以你将启动(内部这就是 Ask 的工作方式)3 个演员,他们将完成“他们自己的”未来。因此,这也会给发送者带来一些成本,因为它必须启动这些特殊目的参与者(比普通参与者小,但仍然如此)。
- 是的,您需要以某种方式标记这些消息。因此,您会发送一些 ID,并且响应必须包含相同的 ID,然后您知道它是“哦,这是 A 的响应”等。我认为这是这里推荐的方式。
- 有一个contribAkka 中提供的模式称为聚合器,它是为此用例设计的,因此您可能需要检查一下:http://doc.akka.io/docs/akka/2.3.4/contrib/aggregator.html http://doc.akka.io/docs/akka/2.3.4/contrib/aggregator.html但是,我想您是否喜欢它很大程度上取决于个人品味。
我个人最喜欢的(我们倾向于避免ask
一般来说)会在一个中标记请求Envelope(id, payload)
所以响应也可以包含在这样的中Envelope(id, response)
。如果您决定将它们称为简单的信封或更多带有领域术语的名称,则由您决定。
希望这可以帮助。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)