Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Reactor Mono<Void> is recognized as an empty Mono?

Here is the piece of code

@Test
public void test_mono_void_mono_empty() {
    Mono.just("DATA")
        .flatMap(s -> Mono.just(s.concat("-")
                                 .concat(s))
                          .doOnNext(System.out::println)
                          .then())
        .switchIfEmpty(Mono.just("EMPTY")
                           .doOnNext(System.out::println)
                           .then())
        .block();
}

that gives the following result to the console:

DATA-DATA
EMPTY

That means that the chain in the first flatMap was recognized as an empty one.

On the other hand Reactor has the following class MonoEmpty that is returned by a Mono.empty() method. On top of that, the method says the following:

/**
 * Create a {@link Mono} that completes without emitting any item.
 *
 * <p>
 * <img class="marble" src="doc-files/marbles/empty.svg" alt="">
 * <p>
 * @param <T> the reified {@link Subscriber} type
 *
 * @return a completed {@link Mono}
 */
public static <T> Mono<T> empty() {
    return MonoEmpty.instance();
}

without emitting any item - but I emitted Void typed object with then() method.

What is the explanation of that?

like image 489
Serhii Povísenko Avatar asked Dec 05 '19 13:12

Serhii Povísenko


People also ask

Is Mono void same as mono empty?

Mono<Void> is a type. Mono. empty() is a method invocation that returns a Mono that that completes without emitting any item.

What does mono void mean?

Mono<Void> should be used for Publisher that just completes without any value. It is intended to be used in implementations and return types, input parameters should keep using raw Publisher as much as possible. Note that using state in the java. util.

How do you know if a flux is empty?

customerFlux. collectList() is resulting in a Mono which contains an empty list when the originating Flux is empty. Therefore, the Mono is not empty (because it contains an empty list) and ok() is invoked.


2 Answers

A given Mono can publish either nothing, or a single value before sending a completion signal. (It can't publish null - the reactive spec forbids it.) The generic type of the Mono denotes the type of the object that might be emitted - but there's no guarantee it will be emitted.

A Mono<Foo> for example can emit just a completion signal, or an instance of Foo and then a completion signal.

There's two common scenarios where a value may not be published - the first is if a value may or may not exist (such as searching for an item in a database or collection). In that case, you'd still use a Mono<SomeType>, and it may or may not emit a SomeType instance. The second scenario is if a value will definitely never be published (often used when you just need notification that a task has completed), and for that, by convention, Mono<Void> is always used. then(), in your above example, falls into the second case.

The reason that Mono<Void> is a special case is that, as you point out, Void is a class that can never be instantiated by design. There's therefore no such thing as an instance of Void, which means the Mono can never emit a value before its completion signal.

The logical conclusion therefore is that a publisher of type Mono<Void> can never emit a value, only a completion signal - and so it is used as such.

like image 154
Michael Berry Avatar answered Sep 25 '22 01:09

Michael Berry


Okay, the answer is in the official java doc that says The Void class is an uninstantiable placeholder class to hold a reference to the Class object representing the Java keyword void.

That means that its main idea is simply to represent the void return type as a class and contain a Class<Void> public value. That's it. Besides, it's not instantiable as the constructor is private. All of that subsequently means that the only value we can assign to a Void variable is null what always is recognized as empty Mono.

helpful discussion: Java generics void/Void types

like image 33
Serhii Povísenko Avatar answered Sep 21 '22 01:09

Serhii Povísenko