Search code examples
javareactive-programmingproject-reactor

How to handle file access in a reactive environment


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?


Solution

  • 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.