我有Akka Stream流程,它使用alpakka从文件读取,处理数据并写入文件。我想在处理n个元素后停止流量,计算持续时间和呼叫系统终止的时间。我怎样才能实现它?
我的流程看起来像这样:
val graph = RunnableGraph.fromGraph(GraphDSL.create() { implicit builder: GraphDSL.Builder[NotUsed] =>
import GraphDSL.Implicits._
sourceFile ~> mainFlow ~> sinkFile
ClosedShape
})
graph.run()
你知道吗?感谢
答案 0 :(得分:1)
这里不需要GraphDSL。
val doneFuture = (sourceFile via mainFlow.take(N) runWith sinkFile) transformWith { _ => system.terminate() }
要获得时间,您可以使用akka-streams-contrib
:https://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")
}