簡體   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