I’m refactoring some blocking code to reactive (using Reactor). I think most of the methods in the java.nio.file.Files
class are blocking.
Is it right if I replace a method like:
public boolean exists() { return Files.exists(path); }
with:
public Mono<Boolean> exists() { return Mono.fromSupplier(() -> Files.exists(path)); }
I think it’s necessary, especially when cheap HDDs are used.
Or does a library exists in Reactor for this kind of file manipulation?
Advertisement
Answer
Generally yes, but your code misses one important part: assigning a scheduler.
It does not really matter whether some call is decorated by wrapping it into a Mono
. What matters is on what Scheduler (thread) that code runs. Your code misses a .subscribeOn(boundedElastic())
call.
(Schedulers.boundedElastic()
is a good choice for work that involves blocking I/O).
Alternatively, a thread running the code can be changed with a .publishOn()
call. E.g. if you deal with an existing Flux<Path>
(instead of a simple Path
value as is in your case), you can use a .publishOn()
to switch threads and a simple map()
to call the blocking method. For example:
Mono.just(path).publishOn(Schedulers.boundedElastic()).map(Files::exists)
also achieves the goal, though is more ugly.