What is reactive programming?
Reactive programming is all about dealing with asynchronous data streams and a specific propagation of change. This means implementing modifications to the execution environment in a certain order.
Let’s have a look at a real life example to explain this: Alain wants to spend the evening with his colleague Tim. They want to eat pizza and watch the Game of Thrones finale. Let’s outline his available options:
- The synchronous approach: Alain finishes work. He goes to the pizzeria, orders pizza and waits till it is done. When he gets the pizza, he then picks up Tim and finally makes it home and starts the final episode.
- The asynchronous approach: Alain orders pizza online, phones Tim, invites him to come over. He heads home, then the pizza gets delivered. He starts watching the episode while eating the pizza. He does not wait for Tim to show up before starting to eat or start watching the episode.
- The reactive approach: Alain orders pizza, phones Tim, invites him to come over, heads home. The pizza gets delivered. This time, Alain waits for Tim to arrive and after Tim arrives, he starts the episode and they eat pizza together.
The synchronous approach takes way too long. He has to go to the pizzeria, wait for the pizza to be ready (he won’t be able to do something else) and leave with the pizza. Alain would probably have wanted to cancel the whole thing before he gets home. When Alain would use the asynchronous approach, he would have eaten the whole pizza and watched the episode before Tim even arrived. Tim would not like this.
The only approach that makes sense is the reactive approach. Alain waits till all the asynchronous actions are completed and then proceeds with further actions.
What does reactive programming solve?
Let’s say there is a publisher of data and a consumer of that data. We have an application that deals with data at a large scale and should process data that is resilient in the face of data coming in, errors in the system and slow downs in the system.
Should the publisher keep feeding the consumer data if it can’t handle the speed of the data and overload it? Should the user expect the program to remain unresponsive till the consumer catches up? Should the publisher know about a crash of the consumer or should he just keep passing data that will not be used?
Reactive systems make these problems top priority. So reactive programming makes systems react to changes in data flows.
The reactive manifesto is a document that defines the core principles of reactive programming. It was first published in 2013. It is the bible for the programmers of the reactive programming religion and a must read for everyone starting with this. You should read it to understand what the principles are and what it is all about.
The 4 main principles:
A responsive system is quick to react to all users in order to ensure a consistently positive user experience.
A resilient system applies proper design and architecture principles in order to ensure responsiveness.
The system stays responsive under varying workload. Making the best use of the resources you have available to you.
Reactive systems rely on asynchronous message-passing to establish a boundary between components that ensures loose coupling, isolation and location transparency.
Reactive streams define a set of interfaces of how we might deal with reactive streaming situations. There are four main interfaces:
Publisher – A producer of values that may eventually arrive.
Subscriber – Listens to what is published by the publisher.
Subscription – Publisher communicating with a subscriber.
Processor – Combination of a publisher and subscriber that allows to process data.
A publisher is setting up the potential to publish information, but until you get a subscriber attached to it, it is not necessarily publishing that information. When we look at the imperative way, we start the application and it starts doing stuff. This is totally different in the reactive way, where it gets ready to do stuff and it waits for the signal to consume the results.
The intention from reactive streams was that it would move on to a more real world implementation of this basic specification. One of those implementations is Project Reactor.
Project Reactor translates reactive streams into a framework that you can use. It was started in November 2015 and forms the basis of reactor support in Spring.
In reactive streams we have a Publisher but in Project Reactor they decided to have two specialized Publishers:
Flux – a Publisher of 0 to N elements
Mono – a Publisher of 0 to 1 element
This decision has been made because not everything is a Flux. Sometimes we know that we are expecting to get back a single value or no value at all. So for code optimizations and for being able to work in the real world with this tool, it can be handy to narrow things down to a Mono and use methods specific for a Mono.
R2DBC (Reactive Relational Database Connectivity) is an endeavor to bring a reactive API to SQL databases. It was first announced at SpringOne Platform 2018. It is an incubator to integrate relational databases using a reactive driver.
Reactive Streams – it is founded on Reactive streams providing a fully reactive non-blocking API.
Relational Databases – engages SQL databases with a reactive API, something not possible with the blocking nature of JDBC.
Scalable Solutions – makes it possible to move from the classic one thread per connection approach to a more powerful, more scalable approach.
There are already some clients available for R2DBC. For example:
I only talked about the basic concepts of reactive programming. There is much more to be found on this interesting subject and it has a lot of potential for the future. I encourage everyone to try and start learning more about reactive programming. A good place to start would be: the Spring documentation and a blog post of Matt Raible of Okta.
Java Software Crafter
Ward Stinissen (26) behaalde een Bachelor Toegepaste Informatica aan de PXL Hasselt met afstudeerrichting “Software Management”. Momenteel is Ward aan de slag bij Nexuzhealth waar hij meehelpt aan de ontwikkeling van het elektronisch patienten dossier. Hij werkt dagelijks met technologieën zoals Angular en Go.