使用Akka Streams分散和收集模式的难度

时间:2017-10-10 19:28:16

标签: scala akka-stream

我有一个像这样的对象

case class Foo(id: Int, id1: Option[Int], id2: Option[Int])

这里id1和id2是在两个单独的查找中获得的。所以首先我使用广播进行分散,然后使用合并和groupBy进行聚合。

我写的代码是

val source = Source(List(Foo(1), Foo(2), Foo(3), Foo(4)))
val flow1 = Flow[Foo].map(foo => foo.copy(id1 = Some(Random.nextInt())))
val flow2 = Flow[Foo].map(foo => foo.copy(id2 = Some(Random.nextInt())))
val flow3 = Flow[Foo].groupBy(100, foo => foo.id)
val flow4 = Flow[Foo].reduce{case (foo, fooLookup) =>
     if (fooLookup.id1.isDefined) foo.copy(id1 = fooLookup.id1)
     if (fooLookup.id2.isDefined) foo.copy(id2 = fooLookup.id2)
     else foo
}
val sink = Sink.foreach[Foo](println)
val graph = RunnableGraph.fromGraph(GraphDSL.create(sink) { implicit builder =>
  s =>
     import GraphDSL.Implicits._
     val b = builder.add(Broadcast[Foo](2))
     val m = builder.add(Merge[Foo](2))
     source ~> b
     b ~> flow1 ~> m
     b ~> flow2 ~> m
     m ~> flow3.mergeSubStreams ~> flow4 ~> s.in
     ClosedShape
   })

这不会编译,因为编译器不喜欢flow3.mergeSubStreams。

我的最终目标是id1和id2的查找发生在两个不同的分支上,我应该能够合并并打印具有id,id1和id2的最终对象。

编辑::我的另一个问题是,由于我已将流分割为2,因此一旦处理完2个Foo,reduce函数就会向前移动。现在似乎reduce函数将等待整个流结束,因为它不知道它将接收多少foo。那么有没有办法告诉减速器一旦它收到了一定数量的记录就应该将它传递给接收器。

0 个答案:

没有答案