What is reactive programming and how does it differ from traditional programming?
In the constantly evolving realm of technology, existing technologies are rebranded every decade or so, sparking renewed enthusiasm about them — and reactive programming and steam programming are no exceptions. While stream programming brings four different practices together, the questions remain the same: Why reactive programming? And why now?
The landscape of technology has undergone a drastic transformation over the past 10-15 years. Today, a multitude of devices — like smartphones, watches and other wearable devices, sensors and many others — are seamlessly interconnected to the Internet, generating vast amounts of data floating around. This surge in data has given rise to big data-related challenges like dealing with high frequencies and high volumes of interactions. This is where reactive programming comes into the picture. It is about having an architecture that focuses on four key tenets: scalable, resilient, responsive and event-driven.
Reactive programming is a programming pattern designed for asynchronous, non-blocking and event-driven data processing. In revolves around modeling the data and events as observable data streams with data processing functions implemented to react to any changes in those streams.
Assume a scenario where a task encompasses multiple requests. In this programming method, a request for a particular resource is initiated within that flow, while the other parts of the flow proceed concurrently. Once the data for the request becomes available, a notification along with data in the form of callback function is dispatched to the caller. This callback function facilitates the handling of the response as per the application or user requirements.
In reactive programming, data streams form the actual backbone of the application. Messages, calls, events and even any kind of failures in the processes are going to be carried by a data stream in the form of a response.
When a code is written, data streams must be created for everything — like click events, ingested messages, measures from sensors, availability notifications, HTTP requests, changes on a variable and cache events, so it contains any kind of change you can imagine. However, this will have an adverse effect on the application, as it will inherently become asynchronous.
Need for ‘reactivity’ in Java
In the case of large volumes of data, asynchronous processing is required for a fast, responsive and scalable system. Java follows object-oriented programming, consequently making it difficult to implement asynchronous behavior and making the code complicated and difficult to maintain. This makes reactive programming predominantly beneficial for a pure object-oriented environment, as it simplifies asynchronous workflows.
Java, which originally did not support coroutine language, was not a reactive language. However, the Java Virtual Machine languages such as Scala and Clojure do support native reactive models, meaning that Java does support reactive programming after version 9. It is the most widely used programming language in enterprise development and recent releases have added interfaces for providing reactive stream layers on top of the standard JDK.
How to attain reactivity in Java?
Java 8 was released with reactivity as an integral part of the language, but it was not well received by developers. Fortunately, there are some third-party implementations available for reactive programming in Java that are regularly updated, saving the day for Java developers.
Reactive Streams is a standard to provide a way for asynchronous stream processing with non-blocking back pressure. Java 9 now includes basic interfaces for each of the fundamental reactive stream concepts in the Flow Concurrency library.
RxJava initially employed by Netflix, later was released under an open-source license. It seamlessly integrates with Java 8 using Lambdas, empowering developers with a chance to write asynchronous and event-based programs for both traditional Java and Android Java.
Spring Framework 5.0 incorporates reactive features, equipped with tools for building HTTP servers and clients. For existing Spring users in the web tier, annotations can be leveraged to enhance controller methods and handle HTTP requests for the dispatching of reactive requests and back-pressure concerns to the framework. Spring is incorporated on the Reactor framework but also offers APIs that assist in leveraging its features using a multiple choice of libraries, like Reactor or RxJava. Users have the freedom to choose between Tomcat, Jetty or Netty via Reactor IO and Undertow for the server-side network stack.
Advantages of reactive programming
The benefits of reactive programming are many:
- Performance improvement: Ability to handle enormous volumes of data expeditiously and steadily
- Scalability: Easy to do async-threaded work and complex threading
- Enhanced UX: The application is more responsive to the user
- Simplified updates: It is easier to read and increase the predictability of code changes
Disadvantages
- More memory intensive to store streams of data most of the time (since it is based on streams over time)
- Might feel unconventional to learn at the start (everything in the form of a stream)
- It is also complicated to write unit tests for such asynchronous code
- Debugging of code is even more difficult
Real-life applications
Reactive programming in Java provides a graceful solution for high-load or multi-user applications, as given below.
- Real-time data streaming
- Artificial intelligence and machine learning
- Proxy servers, load balancers
- Server code that serves highly interactive and reactive user experience
- Audio and video apps
- Social networks, chats and games
References
https://spring.io/blog/2016/06/07/notes-on-reactive-programming-part-i-the-reactive-landscape