It certainly took me a while to get used to things – wrapping my head around the whole non-blocking nature of the Node runtime and how it uses a single thread to process requests – and how important it was that I definitely do not block that thread!
Actually, that last part reminded me back to my Java Swing days and it’s ‘Event Dispatching Thread‘ which one always had to be careful not to block at any cost. I digress, but quite similar in ways.
Anyway, for anyone not familiar with the Node.js runtime, it works on a principle where a single thread handles and processes incoming requests on an ‘Event Loop’. Each request is then safely handed off asynchronously to a backend system which will invoke the callback provided by the caller when it has completed the operation. It works in effect by an event driven architecture.
This leads to better utilization of a system’s resources as a large number of requests can now be processed by a small number of threads.
Contrast this to a traditional ‘blocking’ Java Servlet Spec web application where each request is handled by a thread and this thread blocks until it is able to fully process the request. e.g a request to fetch a large amount of data from a database over the network might take a few seconds and until this operation completes, the thread will be blocked from servicing other requests.
Non blocking applications that are asynchronous and event driven are really the essence of reactive programming today and in general help us follow the Reactive Manifesto
Reactive Programming with Java – a brief history
Java 1.8 brought us ‘CompletableFutures’ where futures could be chained together (amongst other things)
Next came Netflix’s RxJava which offered the ‘Observable’ type – facilitating producer ‘push’ based values (rather than consumer pull based) as well as a the Flowable type – which allows ‘Back Pressure’ mechanisms to be implemented i.e. where consumers can express how many items are they ready to process, thus keeping memory usage more controllable and stable.
The Reactive Streams Specification
Eventually a collaboration between engineers from Kaazing, Netflix, Pivotal, Red Hat, Twitter, Typesafe to name a few, defined us all a common API (Reactive Streams) for Reactive Programming in Java. It has since been implemented in Akka, Ratpack, Vert.x and Spring where it was named Reactor. It was finally incorporated into the JDK in Java 9.
The Spring Framework uses Reactor internally for its own reactive support.
Spring 5 + WebFlux
WebFlux brings reactive programming support to Java web applications in Spring Framework 5.
Since WebFlux uses Reactor (Spring’s streaming impl) under the hood, it allows us to build non blocking web applications which enable things like:
- subscribing to a stream of server data from a non-blocking http endpoint – for example subscribe to a constant feed of updating stock quotes
- subscribing with a ‘back pressure’ value – e.g. telling the server that we only want to receive streaming data with ‘X’ records in each response or that we only want the response once every ‘Y’ seconds
Taking it a bit further..
Spring Data ( Spring’s powerful object mapping abstraction) now also has Reactive capabilities baked in, so couple that with, say, MongoDB’s reactive Java driver (whereby data can be streamed from a MongoDB database) and layer a subscription pattern on top of that, then we can truly cook up some awesome reactive apps.