使用akka流程迈出第一步。我有一个类似于从here复制的图表:
innerHTML
我可以使用val topHeadSink = Sink.head[Int]
val bottomHeadSink = Sink.head[Int]
val sharedDoubler = Flow[Int].map(_ * 2)
val g = RunnableGraph.fromGraph(GraphDSL.create(topHeadSink, bottomHeadSink)((_, _)) { implicit builder =>
(topHS, bottomHS) =>
import GraphDSL.Implicits._
val broadcast = builder.add(Broadcast[Int](2))
Source.single(1) ~> broadcast.in
broadcast.out(0) ~> sharedDoubler ~> topHS.in
broadcast.out(1) ~> sharedDoubler ~> bottomHS.in
ClosedShape
})
运行图表
但我怎么能阻止它呢?
在什么情况下我应该这样做(除了没有用 - 商业明智)?
该图包含在actor中。如果Actor崩溃了底层演员的图形会发生什么?它会终止吗?
答案 0 :(得分:2)
如documentation所述,从图表外部完成图表的方法是使用KillSwitch
。您从文档中复制的示例不是说明此方法的好选择,因为源只是一个元素,并且当您运行它时,流将非常快速地完成。让我们调整图表,以便更轻松地查看KillSwitch
的实际操作:
val topSink = Sink.foreach(println)
val bottomSink = Sink.foreach(println)
val sharedDoubler = Flow[Int].map(_ * 2)
val killSwitch = KillSwitches.single[Int]
val g = RunnableGraph.fromGraph(GraphDSL.create(topSink, bottomSink, killSwitch)((_, _, _)) {
implicit builder => (topS, bottomS, switch) =>
import GraphDSL.Implicits._
val broadcast = builder.add(Broadcast[Int](2))
Source.fromIterator(() => (1 to 1000000).iterator) ~> switch ~> broadcast.in
broadcast.out(0) ~> sharedDoubler ~> topS.in
broadcast.out(1) ~> sharedDoubler ~> bottomS.in
ClosedShape
})
val res = g.run // res is of type (Future[Done], Future[Done], UniqueKillSwitch)
Thread.sleep(1000)
res._3.shutdown()
源现在包含一百万个元素,接收器现在打印广播元素。在我们调用shutdown
来完成流之前,流运行一秒,这还不足以流失所有一百万个元素。
如果在actor内部运行一个流,那么为运行流而创建的基础actor(或者actor)的生命周期是否被置于"封闭"的生命周期中。 actor取决于如何创建Materializer。有关详细信息,请阅读documentation。 Colin Breck关于使用actor和KillSwitch
来管理流生命周期的以下博客文章也很有用:http://blog.colinbreck.com/integrating-akka-streams-and-akka-actors-part-ii/
答案 1 :(得分:0)
有一个KillSwitch功能应该适合你。检查其他问题的答案:Proper way to stop Akka Streams on condition