Waiting on multiple Akka FSM messages

≯℡__Kan透↙ 提交于 2019-12-09 13:40:07

问题


I have an Akka FSM actor that runs the following pseudocode after receiving a message while in ReadyState

lookupA ! Wrapper(Lookup("A"))
lookupB ! Wrapper(Lookup("B"))
lookupC ! Wrapper(Lookup("C"))
goto(LookingUpDataState) using DataFound(a = None, b = None, c = None)

The actor then waits for responses which can be either FullResult[T] (extending ServiceResult[T]) or Empty (extending ServiceResult[Nothing]). Successful lookup results are used to populate the DataFound instance's fields and Empty lookup results result in a logged error message and the termination of the actor.

My question is this: how can I determine which lookup failed, so that I can log the failure or fallback to a default value? All I can think of is examining the sender's ActorRef (hacky) or adding a unique ID field to all messages (high overhead).

This is a simple problem to solve using Ask's and Futures. Does an idiomatic Akka solution exist?


回答1:


There's a few patterns you could use here. You will have to resort to one of these options listed below. They all have some trade off (and benchmarking is king anyway), but I've listed them in order of "bad to good",

  • performing the queries in-order, so send A, wait for A response, send B ... But that's horrible - as in needlessly sequential.
  • use the ask pattern, so you'll spin up (internally that's how ask works) 3 actors, and they'll complete "their own" future. So this also has some cost on the sender because it has to start these special purpose actors (smaller than a normal actor, but still).
  • Yes, you'll need to tag these messages somehow. So you'd send some ID and the response must contain the same ID, then you know it's "oh it's the response for A" etc. I would argue that this is the recommended way to go here.
  • there's a contrib pattern available in Akka called the Aggregator, which is designed for this use case, so you might want to check it out: http://doc.akka.io/docs/akka/2.3.4/contrib/aggregator.html However if you like it or not is very much a matter of personal taste I guess.

My personal favourite (we tend to avoid ask in general) would be tagging the requests in an Envelope(id, payload) so the responses can also be wrapped in such Envelope(id, response). If you decide to call these simply envelope or more with domain terminology is up to you.

Hope this helps.



来源:https://stackoverflow.com/questions/24872342/waiting-on-multiple-akka-fsm-messages

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!