Akka Streams在处理n个元素后停止流

时间:2017-04-23 20:17:19

标签: scala akka-stream

我有Akka Stream流程,它使用alpakka从文件读取,处理数据并写入文件。我想在处理n个元素后停止流量,计算持续时间和呼叫系统终止的时间。我怎样才能实现它?

我的流程看起来像这样:

val graph = RunnableGraph.fromGraph(GraphDSL.create() { implicit builder: GraphDSL.Builder[NotUsed] =>
        import GraphDSL.Implicits._

 sourceFile ~> mainFlow ~> sinkFile

ClosedShape
})

graph.run()
你知道吗?感谢

2 个答案:

答案 0 :(得分:1)

这里不需要GraphDSL。

val doneFuture = (sourceFile via mainFlow.take(N) runWith sinkFile) transformWith { _ => system.terminate() }

要获得时间,您可以使用akka-streams-contribhttps://github.com/akka/akka-stream-contrib/blob/master/contrib/src/main/scala/akka/stream/contrib/Timed.scala

答案 1 :(得分:1)

同意@Viktor的说法,首先你不需要使用graphDSL来实现这一点,你可以使用take(n)来完成图表。

其次,您可以使用mapMaterializedValue将回调附加到您的Sink实体化值(反过来应该实现Future[Something])。

  val graph: RunnableGraph[Future[FiniteDuration]] =
    sourceFile
      .via(mainFlow)
      .take(N)
      .toMat(sinkFile)(Keep.right)
      .mapMaterializedValue { f ⇒
        val start = System.nanoTime()
        f.map(_ ⇒ FiniteDuration(System.nanoTime() - start, TimeUnit.NANOSECONDS))
      }

  graph.run().onComplete { duration ⇒
    println(s"Elapsed time: $duration")
  }

请注意,您需要ExecutionContext范围。

修改

即使您必须使用graphDSL,也适用相同的概念。您只需要公开您的接收器的物化Future并在其上进行映射。

  val graph: RunnableGraph[Future[??Something??]] = 
    RunnableGraph.fromGraph(GraphDSL.create(sinkFile) { implicit builder: GraphDSL.Builder[Future[Something]] => snk =>
    import GraphDSL.Implicits._

    sourceFile ~> mainFlow ~> snk

    ClosedShape
  })

  val timedGraph: RunnableGraph[Future[FiniteDuration]] = 
    graph.mapMaterializedValue { f ⇒
      val start = System.nanoTime()
      f.map(_ ⇒ FiniteDuration(System.nanoTime() - start, TimeUnit.NANOSECONDS))
    }

  timedGraph.run().onComplete { duration ⇒
    println(s"Elapsed time: $duration")
  }