An introduction to reactive programming concepts and basics. I aim here to show what's reactive programming, why it's used and show some frameworks and benchmarks that support it.
4. IMPERATIVE
PROGRAMMING
Imperative programming is mostly
sequential and follows a natural flow,
hence it is easy to write.
For backend servers, this follows a thread
per request model. Each request means a
new thread on the server. For millions of
requests that can be costly as each thread
means at least 1-2MB of RAM just for the
thread itself.
Also, this means the thread must be
blocked for any operation even that ’s
outside of our application.
1
• Receive Request
2
• Attempt to retrieve data from database
3
• Block thread and waste memory and CPU
until response
4
• Get data and send it to external system
(BSS, CMS, etc.)
5
• Block thread again until response from
external system
5. REACTIVE PROGRAMMING
Reactive programming is a paradigm that
deals with asynchronous data streams
(sequences of events), which means it
executes modifications to the execution
environment (context) in a certain order.
Using pre-defined threads every request is
assigned to one of the threads and the
threads are NOT BLOCKED by waiting for a
response from DB for example.
It is all about reacting to events, so reacting
to the DB returning with data instead of
actively wait for it.
Functional programming is usually used to
achieve reactivity this is called FRP or
Functional Reactive Programming.
1
• Receive Request
2
• Attempt to retrieve data from database
3
• Don’t block thread and receive another
request while waiting
4
• Get data and send it to external system
(BSS, CMS, etc.)
5
• Process another request while waiting
7. 1. No side effects, as in all our processing data should be immutable.
2. Statelessness.
3. Functions are first class citizens, they are independent of each other.
4. Modularity because set of execution steps is an independent function.
FUNCTIONAL PROGRAMMING RULES
13. With a single thread we can handle a lot of requests, each request is processed in the event loop and we won’t
wait for the response.
It will be sent to a queue (like message queues) and to be processed on receiving an event of completion, the
event of completion is called a callback.
The event loop is a constantly running process that monitors both the callback/task queue and the call stack.
If the call stack is not empty, the event loop waits until it is empty and places the next function from the callback
queue to the call stack. If the callback queue is empty, nothing will happen.
JavaScript is built on this concept, also note that the name event loop and callback can differ from a
language/framework to another.
We can have one thread (JavaScript) or more threads (Java, mostly one per core) with each having their own event
loop.
EVENT LOOPS AND CALLBACKS
16. REACTIVE PROGRAMMING
STREAMS
In RP, any data is considered a stream. So when a
client request all users, a response is returned to
indicate that the request was sent successfully.
A stream is a sequence of ongoing events ordered
in time. It can emit three different things: a value,
an error, or a "completed" signal. We capture
these emitted events only asynchronously.
17. PUBLISHER SUBSCRIBER
Subscriber (Observer): Data stream consumer, it
observes.
Publisher (Observable): Data stream producer, it is
observable.
Subscription: The connection between the
subscriber and publisher, the subscriber can define
some specs like events capacity and choose when
to end the stream.
The subscriber must be non-blocking to be
reactive.
18. BACK-PRESSURE
Backpressure is the actual main difference
between a normal asynchronous pub sub relation
and a reactive non-blocking one.
It means that the publisher should never
overwhelm the subscriber with more requests
than it can handle.
The subscriber defines its boundaries to achieve
this and it can keep requesting in batch number
(i.e. 100 responses more).
19. FUNCTIONAL
MANIPULATION OF
STREAMS (PIPES)
Some reactive libraries allow us to modify the
stream in a functional manner, in some libraries
these are called pipes but they have other names
as well.
What’s important is that they must be purely
functional with no side effect.
20. Rx: Reactive Extension (Rx) are libraries that enable imperative programming languages to compose
asynchronous and event-based programs by using observable reactive streams. The data stream is
called Flowable (multiple data) and Maybe (single result).
They exist for many languages like Java (RxJava), JavaScript (RxJS), Kotlin (RxKotlin), Swift (RxSwift), .NET
(Rx.NET), Python (RxPy) and so on.
Project Reactor (Spring Webflux): Similar to RxJava but implemented for Spring framework. The stream
is called Flux (multiple data) and Mono (single result).
Vert.x: Another java based reactive framework which is extremely powerful and fast, it has Future
(similar to Promise in JS) for data stream.
It is a complete ecosystem and it’s the most powerful reactive library written in any high level
language. It has an app generator https://start.vertx.io/ similar to spring initializr. Other frameworks
like Quarkus and es4x build upon it to provide reactivity.
FRAMEWORKS & LIBRARIES
22. PROS
Can manage millions of request with a small amount of
threads.
Responsive, resilient, elastic and message driven (Reactive
Manifesto) systems.
Generally higher performance for web applications.
Back-pressure.
Perfect when integrating with stream/pub-sub systems like
Kafka or RabbitMQ.
NoSQL databases and drivers naturally support it.
CONS
Can be more complicated to write, not as natural as regular
imperative code backgrounds.
Non-blocking code is harder to write for people coming
from non-functional Support for reactive JDBC is weak
(R2DBC).
Debugging can be really hard.
Easy to mess. Subscriptions must be closed when not in
use.
Still new, support is not like old thread per request models
like servlets.
PROS AND CONS
23. USE IT
High-load and multi-user applications:
◦ Proxy Servers and Load Balancers.
◦ Any application that doesn’t do a lot of processing itself but
delegates the high data processing to another system, like
telecom e-care portals as they delegate to OCS, BSS or
message brokers.
◦ Social Networks.
◦ Games.
◦ Real-time data streaming.
DON’T USE IT
High processing/blocking applications:
◦ If your whole application has to block the thread to do high
processing (i.e. PDF generation in BI applications) then you
probably would benefit from thread per request models
WHEN TO USE
24. Spring Benchmarks
From this link, you can find a comparison of Spring Webflux vs normal Servlet based (Thread per request)
comparison, here is the result (msg/sec), it was done on a single core 1GB RAM server.
25. Check this link for more info, you can find code implementations here.
Basically, vert.x (and frameworks building on vert.x)are the fastest queries.
Spring JDBC/Data JPA will slow down Webflux full potential.
Pg-client is actually made for Vert.x (by Reactiverse) and it’s the fastest to communicate with
databases in a reactive manner.
There is reactive hibernate to use as an ORM and without a big loss. It can directly return data
streams from Mutiny library (Qurakus) but not return a Flux.
Spring Data has Spring Data R2DBC but it is not as ready as Hibernate Reactive.
POLYGLOT BENCHMARK