如何使用Akka流Flow.batch批量从源发出的多个元素

时间:2016-08-21 08:18:47

标签: akka reactive-programming akka-stream

我使用以下代码来测试akka流Flow.batch的行为,但我无法弄清楚为什么结果不符合我的预期:

input

这是输出: Source(1 to 20) .map(x => { println(s"received: ${x}") x }) .batch(max=3, first => first.toString) {(batch, elem) => { batch + "," + elem }} .runWith(Sink.foreach(x=>{ Thread.sleep(4000) println("Out:" + x) }))

这里有几点我无法理解:

  • 首先,我的水槽慢得多。我希望在下游发射之前将该项目分批组合,例如:Out:1,2,3;出:4,5,6;出:7,8;出:9,10,11等。相反,它只被批处理一次(1,2,3),但随后逐个发出元素而不是批处理。
  • 为什么我在正确的开头收到了4个项目(收到:1,...,收到:4),而事实上,我只设置了max = 3(批次(max = 3))。
  • 因为源比接收器快得多。我希望元素的发射速度要快得多,例如:收到:7,收到:8,收到:9;然后出局:7,8,9;但事实上,只有在Sink的println函数执行后才会一个接一个地发出它。

我试图将地图更改为mapAsync,但行为仍然不是我想要的:


received: 1
received: 2
received: 3
received: 4
Out:1,2,3
received: 5
Out:4
received: 6
Out:5
received: 7
Out:6
received: 8
Out:7
received: 9
Out:8
received: 10
Out:9
received: 11
Out:10
received: 12
Out:11
.... so on ....
received: 19
Out:18
received: 20
Out:19
Out:20

感谢。

1 个答案:

答案 0 :(得分:1)

代码中的任何地方都没有异步边界,它将在单个线程上运行。基本上,虽然你的Thread.sleep()执行没有在这个设置中发生其他进展,即批处理不会发生(因为线程在Thread.sleep上被阻止)。如果您有这样的设置,那么您可以使用groups()而不是batch,或者可能使用groupsWithin()。如果您仍想尝试batch(),请尝试节流阶段而不是添加睡眠。节流阀不会阻塞线程,因此上游进度(批处理)不受影响。