使用akka期货和参与者来并行化列表

时间:2011-10-12 04:55:23

标签: scala actor akka future parallel-processing

我想向演员发送消息列表,在将来立即收到回复,然后在返回调用方法之前等待所有期货完成。从阅读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中并返回)。

2 个答案:

答案 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]