使用Akka Streams,我如何知道源何时完成?

时间:2019-02-02 10:47:08

标签: elasticsearch akka akka-stream reactive-streams alpakka

我有一个Alpakka Elasticsearch Sink,我在两次请求之间一直保持联系。收到请求时,我从HTTP请求中创建一个Source,并将其转换为Elasticsearch Source的{​​{1}},然后使用WriteMessage运行它。

  1. 如何在源完成后得到通知?似乎没有有用的东西。
  2. 源代码的完成是否会传递给接收器,这意味着我必须每次创建一个新的源代码?
  3. 如果对上述回答是肯定的,是否可以在mySource.runWith(theElasticseachSink)的帮助下将它们解耦?

我的目标是知道HTTP下载何时完成(包括它经过的Flow.fromSourceAndSink)并能够重新使用接收器。

2 个答案:

答案 0 :(得分:0)

您可以根据需要绕过流的单个部件,甚至可以通过围绕整个executabe图(这些都是immutables)。运行()调用物化的流动,但不会改变您的图形或它的部分。

1) 既然您想知道HttpDownload是何时传递的,为什么不使用完整的图形Future [Done]?假设您对elasticsearch的调用是异步的,那么这应该是相等的,因为您的接收器只会触发该调用,而不会等待。 你也可以使用Source.queue(https://doc.akka.io/docs/akka/2.5/stream/operators/Source/queue.html),只是增加你的消息队列,然后重新使用已定义的图,从而你可以需要proocessing时添加新的消息。这也实现了SourceQueueWithComplete,允许您停止流。 除此之外,重复使用水槽所需的地方,而无需等待使用它的另一个流。

2)如上所述:不,您不需要多次实例化接收器。

最好的问候, 安迪

答案 1 :(得分:0)

事实证明,Alpakka的Elasticsearch库也支持流动形状,因此我可以让我的源代码通过它并通过实现未来的任何接收器运行它。 Sink.foreach在这里可以很好地用于测试目的,例如在https://github.com/danellis/akka-es-test中。

Flow fromFunction { product: Product =>
    WriteMessage.createUpsertMessage(product.id, product.attributes)
} via ElasticsearchFlow.create[Map[String, String]](index, "_doc")

先定义es.flow,然后

val graph = response.entity.withSizeLimit(MaxFeedSize).dataBytes
    .via(scanner)
    .via(CsvToMap.toMap(Utf8))
    .map(attrs => Product(attrs("id").decodeString(Utf8), attrs.mapValues(_.decodeString(Utf8))))
    .via(es.flow)

val futureDone = graph.runWith(Sink.foreach(println))

futureDone onComplete {
    case Success(_) => println("Done")
    case Failure(e) => println(e)
}