After more than a year of work, multiple milestones and fine tuning based on much feedback, I have the pleasure of announcing Reactor 3 General Availability. You will find Reactor Core 3.0.2.RELEASE on Maven Central.

What is Reactor 3 ?

Reactor 3 provides a powerful and efficient reactive programming model for Java 8 based applications. The model builds upon the experience of both Reactor 2 and RxJava 1 and introduces a fluent way to compose asynchronous backpressure-ready event processing. Spring Framework 5 uses Reactor 3 to build and eventually expose a complete reactive story.

Its design relies on an extensible execution model that favors event processing colocation. Typically, Reactor will be jumping threads between event flow stages only when explicitly asked so. For instance, in-memory operations such as list access or payload transformation do not usually require a thread boundary. If the operation producer or receiver might take time, users are expected to operate their flow with Flux#publishOn / Mono#publishOn or Flux#subscribeOn / Mono#subscribeOn and choose a Scheduler to run on. Alternatively, if a user is combining the results of many Publisher as with merge or concat, Reactor will implicitly deal in a thread-safe way with various potential thread boundaries. In effect a flow stage hosted by a Publisher might be traversed by a producing and a receiving thread at least.

All of this is implemented in compliance with the behaviors defined by the Reactive Streams specification. Reactor works at making the spec a commodity for library writers or Spring developers with pre-made operators you would apply in a streaming and/or asynchronous scenario.

Mono and Flux

A flow definition is what Reactor calls a chain of Flux or Mono depending on the volume flowing into the defined stream. These types implement Reactive Streams Publisher at every stage and can be passed around generically. Why two reactive types then ? Because the cardinality matters to Reactor. A Flux will observe 0 to N items and eventually terminate successfully or not. A Mono will observe 0 or 1 item, with Mono<Void> hinting at most 0 item.

Let’s look at the following blocking API :

interface BlockingUserRepository { User get(String id); List<User> findAll(); void save(User data) throws RepositoryException; List<User> findAllByUsernameLike(String s); }

Using plain Reactive Streams Publisher , we would get the following contract :

interface ReactiveUserRepository { Publisher<User> get(String id); Publisher<User> findAll(); Publisher<Void> save(Publisher<? extends User> source); Publisher<User> findAllByUsernameLike(String s); }

But with Reactor we can keep semantic evidence of the intended cardinality :

interface ReactorUserRepository { Mono<User> get(String id); Flux<User> findAll(); Mono<Void> save(Publisher<? extends User> source); Flux<User> findAllByUsernameLike(String s); }

Since both Mono and Flux implement Publisher we can easily pass any reference of them as Reactive data source while returning explicit semantics with Mono<Void> fluent API :

// ReactorUserRepository userRepository; userRepository.save(Mono.fromCallable(() -> new User("thomas"))) .doOnSuccess(res -> success()) .subscribe(); userRepository.save(Flux.just(new User("bob"), new User("robert"))) .doOnSuccess(res -> success()) .subscribe();

Keep in mind that Flux and Mono are meant for data producers that might take time. To manage reentrance and thread safety, operators must sometimes add some overhead in the executed flow. Still, efficiency is a core focus and we are getting regular reports from our engine contributor David Karnok. Reactor 3 is currenly one of the most efficient reactive library on the JVM. In addition to these directly related benchmarks, we now benefit from RxJava 2 community feedback as well since it conceptually derives from the same smith and forge: Reactive Streams Commons.

What’s next ?

We are working on 3.0.3 for the next immediate weeks and we keep in sync with the latest needs from Spring 5, CloudFoundry and latest research from Reactive Streams Commons.

In priority we will address:

New Testing support: Reactor 3 was scheduled with testing support, however initial feedbacks raised a few user experience issues. We are now working on delivering that missing bit. Meanwhile, users can easily duplicate the isolated TestSubscriber from our test for their needs.

Guidance: While Reactor 3 is becoming increasingly popular, we are still working with a lot of human interaction internally or externally, power user with Rx knowledge and the quick tutorial contributed by Sebastien Deleuze. You will find more resources at the end of this post but we have started establishing some end-to-end scenarios that we find concrete, valuable and will help shaping an official reference reactor guide.

Reactor IPC

IPC stands for Inter-Process Communication and Reactor IPC is an ongoing initiative to answer the question “how to get away from the JVM in a Reactive Streams fashion”. We are working on an initial set of implementations with Reactor Kafka, Reactor Aeron & Reactor Netty. In fact a lot of things is going on right now with contract redesign and Reactor Kafka/Netty work that support some of the new Spring reactive stories. The intent of the IPC umbrella is not to create new web or messaging frameworks but reactive drivers applications or libraries alike can build on. They transform a given runtime input/output in Flux and Mono or Subscriber , propagating reactive backpressure up to the IO access layer. Expect a lot of news about these initiatives over the coming months.

Credits

Let’s take some time to credit the people behind this release. David Karnok is the main architect of the new Reactor engine and leads Reactive Streams Commons research effort. Spring, Eclipse STS and CloudFoundry Client teams were instrumental in contributing design improvements and feedbacks as well. Beyond Pivotal, MuleSoft has been massively helpful and proactive about the latest development.

RxJava 1 brought mainstream Reactive to the JVM and its complete functional Rx algebra has become an industrial-standard which we align with. It inspired the game-changing specification we implement with Reactive Streams and brought together JVM key players such as Netflix, Oracle, Pivotal, Typesafe, Red Hat and many more.

Resources

Stay tuned for more reactive stories ! The Reactor journey at Pivotal is only getting started, after much effort and research these past years we are excited to deliver a new experience. Our value proposition is directly correlated to Spring OSS, we have a unique opportunity to deliver reactive pipelines in an end-to-end fashion across all Spring portfolio.

To conclude, Spring and Reactor are praising our community, you, for the enormous support, encouragements and feedbacks. The feedback loop we have established for years is more than a nice pragmatic collaboration, it’s what we all need to transform our industry step by step.