(C) Tandem Crystals Pvt. Ltd.

Reactive Programming

A Mutiny perspective

What is reactive programming?

Reactive programming is a great way to create modern, responsive, and scalable applications. The reactive programming paradigm can handle both asynchronous and non-asynchronous code. Developers can write code that handles multiple tasks at once without having to stop the main thread from executing

You are able to create data streams of anything, not just from click and hover events. Streams are cheap and ubiquitous, anything can be a stream: variables, user inputs, properties, caches, data structures, etc.

The hardest part of the learning journey is thinking in Reactive. It’s a lot about letting go of old imperative and stateful habits of typical programming, and forcing your brain to work in a different paradigm.

Why reactive programming?

We say We love it !!. It’s subjective. Given the recurring cost that we pay for cloud infrastructure, traditional way of programming, tech stacks costs us more.

One of the key ingredients for resource efficiency is to move away from traditional software stacks where each net- work connection is associated with a thread, and where I/O operations are blocking. By moving to asynchronous I/O, one can multiplex multiple concurrent connection processing on a limited number of threads, translating to lesser number of vCPUx. Sounds interesting. However this requires abandoning familiar imperative programming constructs.

Why the hate?

Traditional imperative programmers find it difficult to adopt and worry about the feeling of magic added to the code.

request.ifNoItem().after(ofMillis(100))
    .failWith(() -> new TooSlowException("💥"))
    .onFailure(IOException.class).recoverWithItem(fail -> "📦")
    .subscribe().with(
        item -> log("👍 " + item),
         err -> log(err.getMessage())
    );
//smallrye.io/smallrye-mutiny/latest/

Class room trainers find it difficult to train someone from imperative to reactive programming. It is easier to train a newbie directly on to reactive programming.

Asynchronous is hard to grasp for most developers, and for good reasons. Thus, the API must not require advanced knowledge or add cognitive overload. However, this is never a silver bullet. Imperative programming has it’s great advantages and for most cases it suites well.

Ok. Why Mutiny?

Simply, our team loves it. Technically with 10% code size of similar libraries, we could do blocking and non blocking code. Easier to train fresh programmers. Great documentation. Community support. Core contributors are our favourite open source commiters.

In a nut shell, Mutiny is

Event-Driven – listen for events and handle them,

API Navigability – it’s event-driven nature, the API is built around the type of events and drive the navigation based on the kind of event you want to handle,

Simplicity – Mutiny provides only two types (Multi and Uni), which can handle any kind of asynchronous interactions. Compare it with CompletableFuture and CompletionStage, you will understand why.

The Uni and Multi Type

A Uni is a specialised stream that emits only an item or a failure. Typically, Uni are great to represent asynchronous actions such as a remote procedure call, an HTTP request, or an operation producing a single result.

Uni type

Uni provides many operators that create, transform, and orchestrate Uni sequences.

As said, Uni emits either an item or a failure. Note that the item can be null, and the Uni API has specific methods for this case.

Uni.createFrom().item(1)
        .onItem().transform(i -> "hello-" + i)
        .onItem().delayIt().by(Duration.ofMillis(100))
        .subscribe().with(System.out::println);

Multi type

A Multi represents a stream of data. A stream can emit 0, 1, n, or an infinite number of items.

You will rarely create instances of Multi yourself but instead use a reactive client that exposes a Mutiny API. Still, just like Uni there exists a rich API for creating Multi objects

Cancellable cancellable = multi
        .subscribe().with(
                item -> System.out.println(item),
                failure -> System.out.println("Failed with " + failure),
                () -> System.out.println("Completed"));

If you like this, love the library, give a star here https://github.com/smallrye/smallrye-mutiny