web-dev-qa-db-ja.com

ブロッキングI / OタスクのParallelFluxとflatMap()

ブロッキングタスクを含むProjectReactorチェーンがあります(ネットワーク呼び出し、応答を待つ必要があります)。複数のブロッキングタスクを同時に実行したいのですが。

ParallelFluxまたはflatMap()のいずれかを使用できるようですが、必要最低限​​の例です。

Flux.just(1)
    .repeat(10)
    .parallel(3)
    .runOn(Schedulers.elastic())
    .doOnNext(i -> blockingTask())
    .sequential()
    .subscribe()

または

Flux.just(1)
    .repeat(10)
    .flatMap(i -> Mono.fromCallable(() -> {blockingTask(); return i;}).subscribeOn(Schedulers.elastic()), 3)
    .subscribe();

2つのテクニックのメリットは何ですか?一方が他方よりも優先されますか?代替手段はありますか?

16
Corin Fletcher

parallelは、パフォーマンスを目的としたタスクの並列化、および「Rails」または「グループ」間での作業のディスパッチ用に調整されています。各グループは、Schedulerに渡すrunOnから独自の実行コンテキストを取得します。つまり、CPUを集中的に使用する作業を行うと、すべてのCPUコアが機能するようになります。しかし、あなたはI/Oバウンドの仕事をしています...

したがって、あなたの場合、flatMapがより良い候補です。並列化のためのflatMapの使用は、オーケストレーションに関するものです。

flatMapとはわずかに異なるflatMapSequentialのフレーバーを数えない場合、これらはほぼ2つの選択肢です(concatMapは実際には並列化を許可していません)。

13
Simon Baslé