15

Project Reactor 3.1.5.RELEASE

Consider this:

Flux.range(0, 10)
    .publishOn(Schedulers.parallel())
    .subscribe(i -> LOG.info(i));

I am expecting the subscriber to run in multiple threads, but it runs only in one:

2018-03-26 12:30:08.693  INFO 89770 --- [     parallel-1] d.a.Application    : 0
2018-03-26 12:30:08.693  INFO 89770 --- [     parallel-1] d.a.Application    : 1
2018-03-26 12:30:08.693  INFO 89770 --- [     parallel-1] d.a.Application    : 2
2018-03-26 12:30:08.693  INFO 89770 --- [     parallel-1] d.a.Application    : 3
2018-03-26 12:30:08.694  INFO 89770 --- [     parallel-1] d.a.Application    : 4
2018-03-26 12:30:08.694  INFO 89770 --- [     parallel-1] d.a.Application    : 5
2018-03-26 12:30:08.694  INFO 89770 --- [     parallel-1] d.a.Application    : 6
2018-03-26 12:30:08.694  INFO 89770 --- [     parallel-1] d.a.Application    : 7
2018-03-26 12:30:08.694  INFO 89770 --- [     parallel-1] d.a.Application    : 8
2018-03-26 12:30:08.694  INFO 89770 --- [     parallel-1] d.a.Application    : 9

The documentation tells my expectations are correct (http://projectreactor.io/docs/core/release/reference/#threading). Could someone explain to me what's going on there?

Mikhail Kadan
  • 556
  • 1
  • 5
  • 15

1 Answers1

31

Reactive flows are sequential in nature and publishOn just tells the source where to emit each value one after the other. You need to tell the flow to go parallel via parallel, then specify the scheduler via runOn:

Flux.range(0, 10)
.parallel()
.runOn(Schedulers.parallel())
.doOnNext(i -> LOG.info(i))
.sequential()
.subscribe();
akarnokd
  • 69,132
  • 14
  • 157
  • 192
  • That worked, thank you. If I get it right, this sequential behaviour is by Reactor design, and not only for `Flux.just()` / `Flux.range()` / etc. So I should actually expect every `Publisher` (e.g. returned from third-party libraries) to be sequential and force it to work in parallel mode with a call to `parallel().runOn()`? Or is it a better way to use `flatMap()` with a `subscribeOn()` inside, I don't know which is a best practice in this case? – Mikhail Kadan Mar 26 '18 at 15:50
  • No, it is an universal Reactive Streams design; RxJava behaves the same way. Otherwise it depends which is better. – akarnokd Mar 26 '18 at 16:13
  • 2
    about choosing between parallel and flatmap, see this answer: https://stackoverflow.com/a/43273991/1113486 – Simon Baslé Mar 27 '18 at 09:05