UPDATE 2023/01/31
Actually you anyway should use .subscribeOn() because even if you call your fire-and-forget function which returns Mono<Void>
it is not guaranteed that within that reactive chain will be switching of executing thread or it will happen immediately (depends on the code inside that fire-and-forget function, more specificaly, operators that used on the chain).
So you may run into situation when your fire-and-forget function will be executed on the same thread that called this function, so your method will not return until this function is completed.
The case when fire-and-forget function returns Publisher<Void>
:
public Flux<Data> search(SearchRequest request) {
return searchService.search(request)
.collectList()
.doOnNext(data ->
// anyway call subscribeOn(...)
fireAndForgetOperation(data)
.subscribeOn(...)
.subscribe()
)
.flatMapMany(Flux::fromIterable);
}
public Mono<Void> fireAndForgetOperation(List<String> list) {
...
}
The case when fire-and-forget function is just a common void
returning method:
public Flux<Data> search(SearchRequest request) {
return searchService.search(request)
.collectList()
.doOnNext(data ->
Mono.fromRunnable(() -> fireAndForgetOperation(data))
.subscribeOn(...)
.subscribe()
)
.flatMapMany(Flux::fromIterable);
}
public void fireAndForgetOperation(List<String> list) {
...
}
Also you should consider what Scheduler
you need to provide, depending on the nature of your fire-and-forget function.
Basically there are two scenarios:
1) If your fire-and-forget function does CPU-Bound work.
Then you want to specify Schedulers.parallel()
inside subsribeOn()
2) If your fire-and-forget function does IO work (actually no matter in this case if it would be blocking or non-blocking IO).
Then you want to specify Schedulers.boundedElastic()
inside subsribeOn()
So, using this approach you will truly return immediately after firing your fire-and-forget function