I'm using ScatterGatherFirstCompletedRouter
which returns the answer of the first actor that finishes. This works fine, but some of the other actors time out. Even if I catch the timeouts, it's still a waste of time and resources. I could send a Kill
to the actors, but this emits a different message and still doesn't do anything about time (for some reason). What's the best way to handle this?
Asked
Active
Viewed 131 times
0

Noel Yap
- 18,822
- 21
- 92
- 144
-
1Yo can implement your routees in a way where them will perform calculations inside Cancellable Futures (http://stackoverflow.com/questions/16020964/cancellation-with-future-and-promise-in-scala/16050595), handle a collection of such Futures with their original senders, on successful Future execution - send the calculation result to itself and route it to the original sender, on receive Kill / Cancel message - cancel all Futures in the collection (and optionally stop itself). – Sergiy Prydatchenko Jul 17 '13 at 08:16
-
2"it's still a waste of time and resources." -- That is a property of ScatterGatherFirstCompletedRouter since you multiply the job although you use only the first result. If you are concerned about resources you should probably use a different routing strategy. – Endre Varga Jul 17 '13 at 09:50
1 Answers
0
Rather than have the direct children of ScatterGatherFirstCompletedRouter
do the meat of the work, have them delegate to another actor. Be sure to keep track of the original requester so that the other actor can send the response to it.
Perhaps it can be cleaner, but here's what I got (where ValidBoardActor
is used with ScatterGatherFirstCompletedRouter
):
class ValidBoardActor extends Actor {
private implicit val timeout = Timeout(12.seconds)
private lazy val generateBoardActor = context.actorFor(s"/user/${GenerateBoardActor.name}")
private def stopProcessing: Receive = {
case _ =>
}
private def processBoards(requester: ActorRef, piecesConfigSpec: Configuration.PiecesConfigSpec*): Receive = {
case board: Board => {
if (board.check) {
requester ! board
context.become(stopProcessing)
} else {
self ! GenerateBoard(piecesConfigSpec: _*)
context.become(processRequests(requester))
}
}
}
private def processRequests(requester: ActorRef): Receive = {
case GenerateBoard(configuration @ _*) => {
generateBoardActor ! GenerateBoard(configuration: _*)
context.become(processBoards(requester, configuration: _*))
}
}
def receive = {
case message => {
self forward message
context.become(processRequests(sender))
}
}
}

Noel Yap
- 18,822
- 21
- 92
- 144