我与一位演员进行了交流
[rabbitmq_management].
只要我从val future = ask(foo, Bar())(1 seconds).mapTo[Row]
val result = Await.result(future, 1 seconds)
发回一个Row
,就可以正常工作。我将如何回答多个foo
:
Row
随后是sender() ! Row()
sender() ! Row()
吗?
答案 0 :(得分:1)
就像其他人在评论中提到的那样,仅当您将所有行作为一条消息发送时,询问模式才有效。使用akka-stream
是为此构建处理器的绝佳解决方案:
val barActor = system.actorOf(Props(new BarActor()))
def runQuery(): Future[Seq[Row]] = {
// complete when EndOfQuery message is received
val runnableGraph = Source.actorRef[DataProtocol](Int.MaxValue, OverflowStrategy.fail)
.takeWhile(elem => {
elem match {
case _:Row => true
case _ | EndOfQuery => false
}
})
.toMat(Sink.seq[DataProtocol])(Keep.both)
// keep both the ActorRef and the Future[DataProtocol]
val (actor, future) = runnableGraph.run()
// issue query to actor
barActor ! Query(actor)
// only Row messages were emitted:
future.map(_.asInstanceOf[Seq[Row]])
}
val data = Await.result(runQuery(), Duration.Inf)
如您在问题中提到的,您将需要停止消息。
答案 1 :(得分:0)
您只能用一个对象进行响应。响应列表呢?
class Foo extends Actor {
def receive = {
case Bar(): sender() ! List.of(Row(), Row())
}
}
val future = ask(foo, Bar())(1 seconds).mapTo[List[Row]]
val result = Await.result(future, 1 seconds)
val row0 = result(0);
val row1 = result(1);
答案 2 :(得分:0)
在没有更多背景信息的情况下,我不确定100%地希望完成什么。我怀疑@lasekio的answer可能正是您想要的。
但是,如果您正在寻找异步流解决方案,那就是说,如果您要在行进入时对其进行处理,而不是等到行全部可用之后(也许是因为行数超出了内存的容纳能力-数百万/ billions),那么,那么,您应该使用Akka Streams。但是由于您似乎反对这种说法,因此有一种选择是纯Akka + Futures:
演员将返回该行,以及下一行的未来。由于您需要一种表示没有更多行的方法,因此在示例中将结果包装在Option
中,其中Some
包含Row
和下一个{{ 1}},而Row
表示没有更多行。您也可以创建单独的类型,或使用None
,只是可以清楚地表明没有其他数据的内容。在演员方面,您可以这样做:
null
在消费者方面:
case _: Bar =>
if (/*... there are more rows...*/) sender() ! Some((Row(), (context.self ? Bar()))
else sender() ! None