3

I have legacy code which returns convert java.util.concurrent.Future, now I am supposed to wrap this method call in a layer which returns reactor publishers Mono or Flux. I believe approach to convert to either of them should be similar so what is the correct way to convert it to Mono.

Suppose for example I am getting Future from API and I need Mono

Aniket Sahrawat
  • 12,410
  • 3
  • 41
  • 67
dvsakgec
  • 3,514
  • 4
  • 28
  • 35
  • I am kind of beginner in this area so any help is greatly appreciated – dvsakgec May 07 '20 at 14:37
  • 1
    this is possible but requires a dedicated thread. That is, the main goal of using Mono/Flux, memory economy, would not be achieved anyway. – Alexei Kaigorodov May 07 '20 at 15:48
  • This is analogous to transforming a `Future` to a `CompleteableFuture` as described here - since a future has no concept of a "callback" when done, you have to block a thread. It's certainly not pretty, but alas there's no sensible way. https://stackoverflow.com/questions/23301598/transform-java-future-into-a-completablefuture – Michael Berry May 07 '20 at 16:07

2 Answers2

0

Given that getting the result from a Future is always going to be blocking, a possible solution would be move that computation to a blocking-friendly scheduler.

 Mono.fromCallable(() -> {
        try {
            Future future = null;
            return future.get();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
 }).subscribeOn(Schedulers.boundedElastic());

You can verify that your code is effectively non-blocking by using BlockHound https://github.com/reactor/BlockHound

Johan Perez
  • 171
  • 1
  • 4
-4

You can use Future::get as supplier in Mono::fromSupplier. Like this, Mono.fromSupplier(Future::get).

Yateen Gupta
  • 68
  • 1
  • 1
  • 10
  • This won't work. `Future::get` throws checked exceptions, which can't be handled with a method reference. The simplest approach would be to supply a lambda with try/catch around the `get` call, `Mono.fromSupplier(() -> { try { return future.get(); } catch(....) { ... } });` – zshift Aug 11 '20 at 14:54
  • @zshift Thats not always true. `Callable` allows checked exceptions. – wilmol Sep 24 '20 at 02:17