Scala 为消息列表运行akka参与者列表
我是akka的新手,我想立即运行一个akka演员列表以获取一个消息列表,例如(我在这里使用scala): 输入 每条消息的输出:Scala 为消息列表运行akka参与者列表,scala,akka,Scala,Akka,我是akka的新手,我想立即运行一个akka演员列表以获取一个消息列表,例如(我在这里使用scala): 输入 每条消息的输出: 1 2 3 如果一次运行3个akka参与者,将列表中的每个参数传递给他们中的每个人,我想稍后使用这些结果作为答案的列表。理想情况下,我正在寻找能够提供以下信息的手术: runActorsForListAndWaitForAnswer(messagesList).map(_.toInt()).sum 我不知道这种方法是否存在,但它会有所帮助。感谢您的帮助,谢谢 首先
1
2
3
如果一次运行3个akka参与者,将列表中的每个参数传递给他们中的每个人,我想稍后使用这些结果作为答案的列表。理想情况下,我正在寻找能够提供以下信息的手术:
runActorsForListAndWaitForAnswer(messagesList).map(_.toInt()).sum
我不知道这种方法是否存在,但它会有所帮助。感谢您的帮助,谢谢 首先,你必须放弃命令式的思维定势。当一切都是异步的时候,Akka味道最好。你不应该在等待另一个演员的回答时阻拦。相反,您可以使用Future[T]
对象并在其上应用函数。此函数将在将来完成时调用
让我们举个例子:您有一个SquareActor
,它接受Int
并返回它的平方。要求其答复的正确方式是:
squareActor ? 9 map {result =>
println(result) //81
}
//more code
非常重要:带有println
的代码块不会被阻塞。更多的代码将立即执行,您的回调方法将在稍后调用
也就是说,我们可以开始实现您的用例。如果我理解正确,你有一个参与者列表和一个整数列表。您希望将每个整数只发送给一个参与者。下面是一个伪代码:
val actors: List[ActorRef] = //...
val numbers: List[Int] = //...
val actorsWithArguments: List[(ActorRef, Int)] = actors zip numbers
val futuresOfAny: List[Future[Any]] = actorsWithArguments map { case (actor, number) => actor ? number}
val futures: List[Future[Int]] = futuresOfAny map {_.mapTo[Int]}
val futureOfAllResults: Future[List[Int]] = Future.sequence(futures)
val future: Future[Int] = futureOfAllResults map { _.sum}
我故意留下显式类型来帮助您遵循代码。让我们一步一步来:
actorsWithArguments
是元组的列表。每个项目包含一对参与者和一条消息-(actor1,message1)
,(actor2,message2)
futuresOfAny
包含参与者的未来
结果列表?编号
调用?
返回一个未来[任何]
,因为:a)结果(尚未)已知,b)Akka不知道结果的类型(回复消息)
futures
是强类型的,因为我们知道每个回复都是Int
。我们mapTo
eachFuture[Any]
toFuture[Int]
futureOfAllResults
采用了从List[Future[Int]]
到Future[List[Int]]
的非常棒的转换。换句话说,我们只是将未来结果列表转换为包含所有项的单个未来结果
future
保留(将来将保留)您的结果
如果你认为这是很多代码,那只是为了教育目的。链接和类型推断可以发挥神奇的作用:
val future = Future.sequence(actors zip numbers map { case (actor, number) => actor ? number} map { _.mapTo[Int]}) map { _.sum} }
最后你得到了你的结果。好吧,你将来会得到的。现在,如果你想将结果发送回另一个参与者,你可以说:
future map {sum => otherActor ! sum}
//or even...
future map otherActor.!
我强烈鼓励您阅读官方文档,使其更加清晰。回答得很好,谢谢!需要一段时间才能以一种更加非阻塞的方式进行思考way@Wojtek:谢谢!。也许可以从阅读一些教程开始(说真的!),其中每个I/O操作都是非阻塞的,需要异步回调?使以后在阿克卡更容易转换范例。
future map {sum => otherActor ! sum}
//or even...
future map otherActor.!