Scala 流observeAsync不异步执行给定的接收器
我正在试验fs2.Stream的并发特性,对它的工作原理有一些误解。我想通过一些并行接收器发送流内容。以下是我尝试过的:Scala 流observeAsync不异步执行给定的接收器,scala,functional-programming,scala-cats,fs2,Scala,Functional Programming,Scala Cats,Fs2,我正在试验fs2.Stream的并发特性,对它的工作原理有一些误解。我想通过一些并行接收器发送流内容。以下是我尝试过的: object TestParallelStream extends App { val secondsOnStart = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) val stream = fs2.Stream.emits(List(1, 2, 3, 4, 5, 6, 7, 8, 9)).c
object TestParallelStream extends App {
val secondsOnStart = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())
val stream = fs2.Stream.emits(List(1, 2, 3, 4, 5, 6, 7, 8, 9)).covary[IO]
val sink: fs2.Sink[IO, Int] = _.evalMap(i => IO {
println(s"[${TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) - secondsOnStart} second]: $i")
Thread.sleep(5000)
})
val executor = Executors.newFixedThreadPool(4)
implicit val cs: ContextShift[IO] = IO.contextShift(ExecutionContext.fromExecutor(executor))
stream.observeAsync(3)(sink).compile.drain.unsafeRunSync() //1
executor.shutdown()
}
//1
打印以下内容:
[1 second]: 1
[6 second]: 2
[11 second]: 3
[16 second]: 4
[21 second]: 5
[26 second]: 6
[31 second]: 7
[36 second]: 8
[41 second]: 9
从输出中可以看出,每个元素依次通过接收器发送
但如果我修改水槽如下:
// 5 limit and parEvalMap
val sink: fs2.Sink[IO, Int] = _.parEvalMap(5)(i => IO {
println(s"[${TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) - secondsOnStart} second]: $i")
Thread.sleep(5000)
})
输出为:
[1 second]: 3
[1 second]: 2
[1 second]: 4
[1 second]: 1
[6 second]: 5
[6 second]: 6
[6 second]: 7
[6 second]: 8
[11 second]: 9
现在我们有4个元素一次通过接收器并行发送(尽管将3
设置为observerAsync
的限制)
即使我用obserasync
替换为observe
我也得到了同样的并行化效果
您能否澄清汇实际是如何工作的?observe
用于在多个汇中传递流元素。它不会更改接收器本身的并发行为
您可以这样使用它:
stream.observeAsync(n)(sink1).to(sink2)