我使用以下代码来测试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)
}))
这里有几点我无法理解:
我试图将地图更改为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
感谢。
答案 0 :(得分:1)
代码中的任何地方都没有异步边界,它将在单个线程上运行。基本上,虽然你的Thread.sleep()执行没有在这个设置中发生其他进展,即批处理不会发生(因为线程在Thread.sleep上被阻止)。如果您有这样的设置,那么您可以使用groups()而不是batch,或者可能使用groupsWithin()。如果您仍想尝试batch(),请尝试节流阶段而不是添加睡眠。节流阀不会阻塞线程,因此上游进度(批处理)不受影响。