我想向演员发送消息列表,在将来立即收到回复,然后在返回调用方法之前等待所有期货完成。从阅读akka文档,我相信Future.sequence是要走的路,但我无法使以下代码正常工作。我从编译器中得到了这个错误:
found : akka.dispatch.ActorCompletableFuture
required: akka.dispatch.Future[Integer]
Error occurred in an application involving default arguments.
futures += secondary ? GetRandom
^
我确信我遗漏了一些显而易见的东西,但根据示例和API文档,下面的代码似乎是“正确的”。
import java.util.Random
import akka.dispatch.Future
import akka.actor._
import Commands._
import collection.mutable.ListBuffer
object Commands {
trait Command
case class GetRandom() extends Command
case class GenRandomList() extends Command
}
class Secondary() extends Actor {
val randomGenerator = new Random()
override def receive = {
case GetRandom() =>
self reply randomGenerator.nextInt(100)
}
}
class Primary() extends Actor {
private val secondary = Actor.actorOf[Secondary]
override def receive = {
case GenRandomList() =>
val futures = new ListBuffer[Future[Integer]]
for (i <- 0 until 10) {
futures += secondary ? GetRandom
}
val futureWithList = Future.sequence(futures)
futureWithList.map { foo =>
println("Shouldn't foo be an integer now? " + foo)
}.get
}
override def preStart() = {
secondary.start()
}
}
class Starter extends App {
println("Starting")
var master = Actor.actorOf(new Primary()).start()
master ! GenRandomList()
}
将一系列消息发送给演员,接收未来并在所有期货完成后返回的正确方法是什么(可选择将每个未来的结果存储在List中并返回)。
答案 0 :(得分:3)
Akka ?
会返回Future[Any]
,但您需要Future[Int]
。
因此,您可以定义一个接受所有类型期货的清单:
val futures = new ListBuffer[Future[Any]]
或者在结果可用后立即将结果转换为Int
:
for (i <- 0 until 10) {
futures += (secondary ? GetRandom) map {
_.asInstanceOf[Int]
}
}
顺便说一句,为了使其有效,您需要更改GetRandom
定义:
case object GetRandom extends Command
并将其与:
匹配case GetRandom =>
答案 1 :(得分:3)
(secondary ? GetRandom).mapTo[Int]