Akka流 - 连接接收器到源?

时间:2016-09-04 20:36:46

标签: akka akka-stream

我遇到sink(或中间flow)实际上可以产生一些必须被推回(或追加)到Source的副作用数据的情况。有没有办法使用流DSL实现这一目标?我可以使用一些阻塞队列或排序它来创建source,然后将数据直接推送到该队列,但这会打破流的抽象。或许有一个我不了解的更好的解决方案?

2 个答案:

答案 0 :(得分:4)

正如Viktor所说,你可以使用圆形图。

例如,partition阶段允许您选择流的特定元素。

  def partitionFunction(i: Int): Int = if (i % 2 == 0) 0 else 1

  val g = RunnableGraph.fromGraph(GraphDSL.create() { implicit builder =>
    import GraphDSL.Implicits._
    val in = Source(1 to 10)
    val out = Sink.foreach[Int](println)

    val addOne = Flow[Int].map(_ + 1)

    val partition = builder.add(Partition[Int](2, partitionFunction))
    val merge = builder.add(Merge[Int](2))

                            in ~> merge ~> partition
    partition.out(0) ~> addOne ~> merge
    partition.out(1) ~> out

    ClosedShape
  })

在此示例中,源in连接到merge的一个输入。整数然后通过partition阶段,这将分开偶数和奇数。

偶数正在经过addOne流程,然后进入merge的第二个输入(这将再次让他们回到partition阶段。)

奇数直接进入接收器out

这允许将一些值反馈回图表,但它很容易导致一个循环(这就是为什么addOne阶段在这里很重要,没有它,偶数会被困在图)。

答案 1 :(得分:1)

Reactive-kafka做了类似的事情(至少在0.8版本中):它将Sink消耗的消息提交回源(Kafka消费者)。

KafkaCommitterSink是实施。它实际上并不是一个圆形的图形,而是它的更新和#39;据我所知,源代码独立于流程。