繁体   English   中英

Akka流mapConcat不适用于循环的RunnableGraph

[英]Akka-streams mapConcat not working with cycled RunnableGraph

我有如下的RunnableGraph broadcastmerge阶段之间有简单的map ,一切都很好。 但是,当涉及mapConcat ,使用第一个元素后此代码将无法正常工作。

我想知道为什么它不起作用。

RunnableGraph.fromGraph(GraphDSL.create() { implicit b =>
import GraphDSL.Implicits._

val M = b.add(MergePreferred[Int](1))
val B = b.add(Broadcast[Int](2))
val S = Source(List(3))

S ~> M ~> Flow[Int].map { s => println(s); s } ~> B ~> Sink.ignore
M.preferred <~ Flow[Int].map(x => List.fill(3)(x-1)).mapConcat(x => {println(x); x}).filter(_ > 0)  <~ B
ClosedShape 
}) 

// run() output: 
// 3
// List(2,2,2)

mapConcat阶段阻止了反馈循环,这是预期的。 考虑以下事件链:

  1. mapConcat函数打印List(2,2,2)
  2. mapConcat阶段需要发出3个可用元素( mapConcat的第一个的需求
  3. 需求必须来自合并阶段,因此来自广播阶段。
  4. 广播级的背压(如果其下游有任何背压)。 它的下游是Sink.ignore (永不背压)和mapConcat本身。
  5. mapConcat背压,如果“是否仍有从先前计算的收集要素”,按照该文档 确实是这样。

换句话说,您的周期是不平衡的。 您在反馈循环中引入的元素要多于要删除的元素。

本文档页面中详细解释了此问题,其中还提供了一些解决方案。 对于您的特定情况,由于您具有过滤器阶段,因此引入大于13的缓冲区将打印所有元素。 但是,请注意,该图形将只是挂起,并且此后不会完成。

S ~> M ~> Flow[Int].map { s => println(s); s } ~> B ~> Sink.ignore
M.preferred <~ Flow[Int].buffer(20, OverflowStrategy.dropHead) <~ Flow[Int].map(x => List.fill(3)(x-1)).mapConcat(x => {println(x); x}).filter(_ > 0)  <~ B

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM