我正在尝试构建一个具有重试反馈循环的图表,但在运行时会在遇到第一次失败时停止执行
val graph = RunnableGraph.fromGraph(GraphDSL.create() { implicit builder ⇒
import GraphDSL.Implicits._
val in = Source(1 to 10).buffer(1, OverflowStrategy.fail)
val out = Sink.foreach(println)
// purely for logging purposes
val m2 = builder.add(Flow[Either[Int, Int]].map(i => {println("flow:" + i); i}))
val mapper = builder.add(Flow[Int].statefulMapConcat{ () =>
var retries = 0
i =>
// deliberately fails to simulate failures
// supposed to retry that element
if (i == 3) {
if (retries > 0){
List(Right(i))
} else {
retries += 1
List(Left(i))
}
} else {
List(Right(i))
}
})
val concat = builder.add(Concat[Int](2))
val broadcast = builder.add(Broadcast[Either[Int, Int]](2))
in ~> concat.in(0)
concat.out ~> mapper ~> m2 ~> broadcast
broadcast.out(1).filter(_.isRight).map(_.right.get) ~> out
broadcast.out(0).filter(_.isLeft).map(_.left.get) ~> concat.in(1)
ClosedShape
})
graph.run()
mapper
有状态流 - 应该做一些任意计算并跟踪重试,输出任何一个实例,如果成功则为对,在出现故障时为Left
稍后我尝试将故障重定向回concat
,以便重试并成功接收到接收器。
输出如下:
flow:Right(1)
1
flow:Right(2)
2
flow:Left(3)
答案 0 :(得分:1)
我还没弄清楚为什么它不适用于Broadcast
,但这是一个带有Partition
的工作版本:
val partition = builder.add(Partition[Either[Int, Int]](2, input => if (input.isRight) 0 else 1))
concat.out ~> mapper ~> m2 ~> partition.in
partition.out(0).map(_.right.get) ~> out
partition.out(1).map(_.left.get ) ~> concat.in(1)