具有自定义行为的分区,可进行下游取消

时间:2018-06-28 10:52:41

标签: scala akka-stream

我需要一个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阶段或操作可以让我做到这一点?

0 个答案:

没有答案