0

I'm looking at examples and reading documentation and I've found some problems while trying to subscribe on Flux in a parallel manner.

I have a 3 functions, as below.

private val log = LoggerFactory.getLogger("main")
private val sequence = Flux.just(1, 2)

fun a() {
    sequence.subscribeOn(Schedulers.parallel()).subscribe { log.info("*** {}", it) }
    sequence.subscribe { log.info(">>> {}", it) }
}

fun b() {
    sequence.subscribe { log.info(">>> {}", it) }
}

fun c() {
    sequence.subscribeOn(Schedulers.parallel()).subscribe { log.info("*** {}", it) }
}

Now, when I run each method separately I have a proper output from functions a() and b(), but output from c() is empty. Is that to be expected, is it by design? If so, why is that happening?

wst
  • 4,040
  • 4
  • 41
  • 59
  • Of course, you're using `just` directly without using `defer` – EpicPandaForce Aug 18 '18 at 08:03
  • I'm just following core reference docs and early examples while trying to experiment a little bit. Since you clearly know explanation, please, make it into an answer. A `defer` doesn't tell me much at this point. – wst Aug 18 '18 at 12:20
  • Actually I'm basing this on RxJava, but if you return `Flux.just` from a `Flux.defer`, you'll be able to schedule it on a different thread, while `just` runs immediately so its execution can't be moved to different thread. I was looking for a construct like `Observable.fromCallable` but it doesn't seem to exist, so I think `Flux.defer { Flux.just` would work. – EpicPandaForce Aug 18 '18 at 14:05
  • Have you had the chance to try it? – EpicPandaForce Aug 19 '18 at 18:36
  • I wrapped as suggested `Flux.defer { Flux.just(1, 2) }`. Method `c()` still doesn't produce output. – wst Aug 19 '18 at 23:19

1 Answers1

5

Flux.just(...) captures value(s) and thus is optimized to execute immediately in the subscribing Thread.

When you use subscribeOn, you change that subscribing Thread from main to something else, making the just truly asynchronous.

In a(), without a subscribeOn that second just would block the main thread just enough that the test doesn't finish before the asynchronous alternative completes.

In c(), there is no such blocking of the main thread. As a consequence, the test terminates before the asynchronous just has had time to emit anything, and that is why you see no output.

To make that more visible, add a Thread.sleep(10) and you'll see some output.

Simon Baslé
  • 27,105
  • 5
  • 69
  • 70