I've coded a little example of what I think it is you are trying to do. First, the two actor classes:
class ParentActor extends Actor{
import context._
import akka.pattern.pipe
implicit val timeout = Timeout(5 seconds)
override def preStart = {
context.actorOf(Props[ChildActor], "child-a")
context.actorOf(Props[ChildActor], "child-b")
}
def receive = {
case "foo" =>
val fut1 = (self ? "bar").mapTo[Int]
val fut2 = Future.traverse(context.children)(child => (child ? "baz").mapTo[Int])
val aggFut = for{
f1 <- fut1
f2 <- fut2
} yield SomeResult(f1, f2.toList)
aggFut pipeTo sender
case "bar" =>
sender ! 2
}
}
class ChildActor extends Actor{
def receive = {
case "baz" =>
sender ! 1
}
}
Then you could test it with this code:
implicit val timeout = Timeout(5 seconds)
val system = ActorSystem("foo")
val actor = system.actorOf(Props[ParentActor])
val result = actor ? "foo"
import system._
result onComplete{
case tr => println(tr)
}
When you run this, it should print Success(SomeResult(2,List(1, 1)))
.
A couple of things here. First, using mapTo
allows the types to be known as opposed to having to deal with Any
. Second, pipeTo
is a good option here to avoid closing over the sender and it also simplifies the code a bit.