我需要一个Akka流阶段,将传入的数据划分为两个下游,如果第一个下游取消,它将取消,但忽略第二个下游的取消。有没有一种方法不需要我编写自己的自定义GraphStage
?
这种情况是我有一个涉及循环的akka流阶段。简化:
import akka.NotUsed
import akka.actor.ActorSystem
import akka.stream._
import akka.stream.scaladsl._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
val flow: Flow[Int, Int, NotUsed] = Flow.fromGraph(GraphDSL.create() {
implicit builder =>
import GraphDSL.Implicits._
val concat = builder.add(Concat[Int](2))
val asyncStage = builder.add(Flow[Int].mapAsync(1) { i =>
Future {
// some long-running calculation goes here
i
}
})
val partition = builder.add(new Partition[Int](2, {
case 0 => 0
case _ => 1
}, eagerCancel = true))
concat ~> asyncStage ~> partition.in
partition.out(1) ~> concat.in(1)
FlowShape(concat.in(0), partition.out(0))
})
问题在于错误处理:
eagerCancel
阶段设置为true意味着concat
阶段取消partition
阶段作为上游抵消。这是在故障从asyncStage
传播之前发生的,这意味着分区阶段的所有下游图形阶段(以及来自接收器的任何物化的未来)都将完成而不是失败;实际的错误丢失了。eagerCancel
设置为false,则partition
将不会取消其上游,并且源将继续引入元素。我需要的是一个分区,如果第一个下游取消,该分区将取消,但忽略第二个。或者,由于Partition
类不支持此操作,因此除了停止取消传递之外,什么也不做。
我当然可以通过编写一个自GraphStage
扩展的自定义类来实现此目的,但老实说,我想尽可能避免这样做。有没有预定义的Akka阶段或操作可以让我做到这一点?