等效于平衡器,在纯净的akka​​流中广播和合并

时间:2019-08-16 14:23:19

标签: scala akka akka-stream

在akka流中,使用图dsl构建器,我可以使用平衡器,广播和合并运算符:

Flow.fromGraph(GraphDSL.create() { implicit builder =>
 val balancer = builder.add(Balance[Result1](2))
 val merger = builder.add(Merge[Result2](2))

 balancer.out(0) ~> step1.async ~> step2.async ~> merger.in(0)
 balancer.out(1) ~> step1.async ~> step2.async ~> merger.in(1)

 FlowShape(balancer.in, merger.out)
}

我如何使用普通的Source,Sink和Flow api实现相同的逻辑?

我可以做这样的事情:

source.mapAsync(2)(Future(...))

但是,正如我所见,从语义上讲,它并不完全等同于第一个示例。

1 个答案:

答案 0 :(得分:1)

使用Source.combineSink.combine。来自documentation

  

有一个简化的API,可用于将源和接收器与诸如Broadcast[T]Balance[T]Merge[In]Concat[A]之类的联结相结合DSL。 Combine方法负责在下面构造必要的图形。在以下示例中,我们将两个来源合并为一个(扇入):

val sourceOne = Source(List(1))
val sourceTwo = Source(List(2))
val merged = Source.combine(sourceOne, sourceTwo)(Merge(_))

val mergedResult: Future[Int] = merged.runWith(Sink.fold(0)(_ + _))
  

对于Sink[T]可以执行相同的操作,但是在这种情况下,它会散开:

val sendRmotely = Sink.actorRef(actorRef, "Done")
val localProcessing = Sink.foreach[Int](_ => /* do something useful */ ())

val sink = Sink.combine(sendRmotely, localProcessing)(Broadcast[Int](_))

Source(List(0, 1, 2)).runWith(sink)