akka - Is it possible to await for second response in Scala -
let's have actor a. expects receive message , once receives message sends 2 messages back.
a extends actor { def receive: receive = { case m1 => context.sender ! m2 context.sender ! m3 } }
and in actor want send message , await 2 responses. know that's easy 1 response in way like
val task = ? m1 await.result(task, timeout)
but i'm not sure whether possible 2 sequential messages.
it important send 2 separate messages need await first of them in place.
you can solve problem introducing intermediate actor in cases when need wait both messages.
this actor this:
class aggregationactor(aactor: actorref) extends actor { var awaitform2: option[m2] = none var awaitform3: option[m3] = none var originalsender: option[actorref] = none def receive: receive = { case m1 => // save sender originalsender = some(sender()) // proxy message aactor ! m1 case m2 => awaitform2 = some(m2) checkifbothmessageshavearrived() case m3 => awaitform3 = some(m3) checkifbothmessageshavearrived() } private def checkifbothmessageshavearrived() = { { m2 <- awaitform2 m3 <- awaitform3 s <- originalsender } { // send tuple s ! (m2, m3) // shutdown, our task done context.stop(self) } } }
essentially has internal state , keeps track of how m1
, m2
responses arriving.
you use like:
def awaitbothmessages(input: m1, underlyingaactor: actorref, system: actorsystem): future[(m2, m3)] = { val aggregationactor = system.actorof(props(new aggregationactor(aactor))) (aggregationactor ? input).mapto[(m2, m3)] } val system = actorsystem("test") val aactor = system.actorof(props(new a), name = "aactor") // awaiting first message only: val firstmessage = aactor ? m1 val first = await.result(firstmessage, duration.inf) // awaiting both messages: val bothmessages: future[(m2, m3)] = awaitbothmessages(m1, aactor, system) val both = await.result(firstmessage, duration.inf)
Comments
Post a Comment