Reactive programming has been around for a while. Long enough to have real experiences in a large base of different business, and long enough to reveal that there is no such thing as a silver bullet. Reactive programming is useful in some cases, but is not one-size-fits-all. Here, we present an overview of the available options in .Net and Java.
What is reactive programming?
First of all, reactive programming is just a programming style based on processing asynchronous data streams. Data streams are a sequence of data items, for example, numbers that have a particular meaning like temperature measurements in a certain facility. In other words, reactive is about handling events in a particular way. The most general steps involved are: an event happens, a value arrives, and a group of chained functions transforms that value or the application reacts based on that value.
As can be seen in Figure 1, reactive architecture is a way to coordinate certain components in order to support solutions, built using reactive programming. There are a lot of libraries to support the creation of reactive applications, and most of them are based on the observer pattern. It is helpful to keep in mind that reactive programming occurs both in the backend and the frontend. That means that reactive applications can be web pages, applications without any user frontend, a group of services, messaging systems or real time data processing events. In other words, almost any kind of application.
And what is the purpose of a reactive application? Well, that’s summed up in the reactive manifesto and basically aims at the following four principles:
- Responsive: The system responds in a timely manner if at all possible. Responsive systems focus on providing rapid and consistent response times, establishing reliable upper bounds so they deliver a consistent quality of service.
- Resilient: The system stays responsive in the face of failure.
- Elastic: The system stays responsive under a varying workload.
- Message driven: Reactive Systems rely on asynchronous message-passing to establish a boundary between components that ensures loose coupling, isolation and location transparency.
Framework / Support for Java
Reactive programming has a lot of support in JAVA. From JAVA 8 to their latest release, they’ve made some attempts to introduce built-in reactivity, yet these attempts are not very popular with developers to date. We identify the following as the most used today:
- RxJava
- Project Reactor
- Akka
- Eclipse Vert.x
RxJava
The first release was back in 2009 and the latest was in March 2019. There is no limitation in the framework, but is mostly used in Android. Actually the library is very generic. It is the implementation of Reactive Extensions or ReactiveX in Java, a library family that includes other languages. Many popular JVM-based programming languages have adaptors for it (Scala, Kotlin, Clojure, etc).
RxJava is based heavily on the observable, subject and scheduler design patterns. This can be seen in their official documentation, when an extensive description of how the library is implemented and the behind scene concepts are shown.
Project Reactor
This one is Reactive-Streams compliant, as it is the more recent library. Project Reactor was released in 2013, similar to RxJava. It represents the reactive API implementation for Spring 5. Of course it’s the natural option if you are using the Spring framework stack. The most relevant characteristics can be seen in the official documentation:
“Reactor is a fully non-blocking reactive programming foundation for the JVM, with efficient demand management (in the form of managing “backpressure”). It integrates directly with the Java 8 functional APIs, notably CompletableFuture, Stream, and Duration. It offers composable asynchronous sequence APIs Flux (for [N] elements) and Mono (for [0|1] elements), extensively implementing the [Reactive Streams](https://www.reactive-streams.org/) specification.
Reactor also supports non-blocking inter-process communication with the reactor-netty project. Suited for Microservices Architecture, Reactor Netty offers backpressure-ready network engines for HTTP (including Websockets), TCP, and UDP. Reactive Encoding and Decoding are fully supported.”
Akka
Lightbend introduced Akka in July 2009 and the latest available release is 2.6.3 as of January 2020. It is based on the actor model, and also its subproject Akka Streams is. Akka along with Vertex are often implemented as reactive microservices which means the combination of microservices architecture and reactive system principles making distributed systems more flexible and reliable as well as increasing the performance.
Available in Java and Scala, its most important characteristics can be found on the landing page as:
- Simpler Concurrent & Distributed Systems. Actors and Streams let you build systems that scale up, using the resources of a server more efficiently, and out, using multiple servers.
- Resilient by Design. Building on the principles of The Reactive Manifesto Akka allows you to write systems that self-heal and stay responsive in the face of failures.
- High Performance. Up to 50 million msg/sec on a single machine. Small memory footprint; ~2.5 million actors per GB of heap.
- Elastic & Decentralized. Distributed systems without single points of failure. Load balancing and adaptive routing across nodes. Event Sourcing and CQRS with Cluster Sharding. Distributed Data for eventual consistency using CRDTs.
- Reactive Streaming Data. Asynchronous non-blocking stream processing with backpressure. Fully async and streaming HTTP server and client provides a great platform for building microservices. Streaming integrations with Alpakka.
Eclipse Vert.x
Eclipse Vert.x is based on the event loop model and does not use a hierarchical model actor as Akka does. It is simpler than Akka, but does not have crash recovery capabilities. Some independent comparisons show it as faster than other alternatives. Actually, it is used in some real-time gaming applications.
Also, it is described as more of a set of tools than a restrictive framework. It’s available for Java, JavaScript, Groovy, Ruby, Ceylon, Scala and Kotlin languages.
A summary of the different options available in Java are shown in Table 1, below. As with almost everything, there is no definitive answer and you should choose the right tool depending on the application’s needs.
Framework / Support for .Net
Thanks to its own platform’s and languages’ evolution focused on multi-paradigm programming that brings functional paradigms (with lambda functions) and declarative programming (with LINQ and extension methods) alongside imperative programming, developers introduced all these major changes in .NET Framework 3.5. After that, Reactive Extensions released its first version. The purpose is the same: to bring in asynchronous data stream processing, operations, and composability.
Reactive programming on .NET framework was introduced initially through the Reactive Extensions (Rx.NET) back in 2009 to provide an implementation for the interfaces IObservable<T> and IObserver<T> added to .NET Framework 4 and Silverlight 4. Since then, it has been evolving into a ubiquitous library. It brings reactive programming not only at the FrontEnd level, also helps tackle inherited complexity from concurrent scenarios.
Besides Rx.NET, we identify the following libraries for .NET:
- Ix & Tx
- UniRx – Unity Reactive Extensions
- Redux.NET
- Orleans
- Akka.NET
- Proto Actor
All these libraries were built on top of Rx.NET API. However this last one was possible thanks to Iterators features introduced back in 2005, with C# 2.0 with the definition of Enumerators, Enumerable Types, Foreach sentence and yield statement, LINQ feature introduced with C# 3.0 and asynchronous programming in C# 5.0.
Ix & Tx
These two libraries bring additional functionalities on top of Rx.NET.
The first one, Ix (Interactive Extensions) brings additional operations for IEnumerable<T> types like Do, Scan, etc. and also to handle asynchronous operations over enumerables.
Tx, on the other hand, expose events from additional sources like Event Logs and Performance Counters in Windows, and Extended Events in the Sql Server.
UniRx
UniRx is an implementation of .NET Reactive Extensions for Unity. It helps solve specific issues across different platforms supported by Unity (Like iOS), and offers a more comprehensive and composable way to implement asynchronous operations.
Redux.NET
Redux.NET combines reactive principles with state management, like Redux js does, and bring them into .NET framework for Silverlight, WPF and UWP applications.
Orleans
Microsoft Research created Orleans as an implementation of Virtual Actor model. Designed for use in the cloud, it offers a way to build a stateful middle-tier applications for high-scale interactive service that demands high throughput with low latency and high availability. Orleans is a programming model that introduces an actor’s abstraction to solve distributed system problems using the actor as a basic building block. This isolated unit encapsulates a behavior and mutable state but only allows communication with other actors through messages.
Akka.NET
Akka.NET is a port from Java/Scala actor model implementation called Akka.
Proto.actor
Proto.actor is another implementation of the actor model. It uses gPRC and Protobuf as a communication and serialization protocols for stability and performance.
Conclusion
Nowadays, both frontend and microservices in the backend are going reactive. Reactive programming improves working in distributed asynchronous systems with its straightforward and easily applicable model.
With several supportive frameworks to apply Reactive architecture, it is the go-to framework to make a system resilient, responsive, and scalable.
We have presented the different options available for Java and .Net, with their advantages and disadvantages. As always, the perfect framework is the one that fits with the particular need. We hope you can make a decision based on the information provided in this article. Or at least use it as your starting point.