Akka-stream mapConcat无法使用循环RunnableGraph

时间:2017-07-26 20:47:04

标签: scala akka akka-stream

我有SELECT TO_CHAR(CAST(TO_TIMESTAMP_TZ(REPLACE('2017-07-27T10:00:00Z', 'T', ''), 'YYYY-MM-DD HH:MI:SS TZH:TZM') AS DATE), 'J') as JULIAN FROM dual 喜欢以下。当RunnableGraphmap阶段之间存在简单broadcast时,一切都很好。但是,当涉及merge时,此代码在使用第一个元素后无效。

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

mapConcat

1 个答案:

答案 0 :(得分:2)

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

  1. mapConcat功能打印List(2,2,2)
  2. mapConcat阶段需要发出3个可用元素中的第一个(2,2,2)
  3. 需求必须来自Merge阶段,因此来自Broadcast阶段。
  4. 如果任何下游背压,广播阶段背压。它的下游是Sink.ignore(从不背压)和mapConcat本身。
  5. mapConcat背压,如果"仍有来自先前计算的集合的剩余元素",根据docs。情况确实如此。
  6. 换句话说,你的周期是不平衡的。您在反馈循环中引入的元素多于您要删除的元素。

    this documentation page中详细解释了这个问题,其中还提供了几个解决方案。对于您的特定情况,由于您具有过滤阶段,因此引入大于 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