Why not CompletableFuture? Reactive Programming is the Rescue!

26 / Aug / 2023 by Rajat Rastogi 0 comments

For many use cases, when you have to perform compute-intensive work, make network calls, or execute some parallel processing, we tend to go with multi-threading. Some temporary threads are spawned to process smaller tasks and merged back to the main request thread post-processing.

CompletableFutures

CompletableFutures were introduced in Java 8 (2014).

The CompletableFuture API is a high-level API for asynchronous programming in Java. This API supports pipelining (also known as chaining or combining) of multiple asynchronous computations into a single result without the mess of nested callbacks (“callback hell“). This API also is an implementation of the future/promise concurrency constructs in Java.

You can use them to tell some worker thread to “go do some task X, and when you’re done, go do the task Y, i.e. dependent on the result of X”. Using CompletableFutures, you can do something with the result of the previous operation, without actually blocking a thread to wait for the result.

CompletableFuture class belongs to the java.util.concurrent package.

The above two future run asynchronously

This shows the blocking nature of Concurrency APIs — Completable Future

Therefore, the Completable Future fails for the many transactions per second requests. Example 10K T/s

Reactive Programming is the Rescue!

Reactive programming is a programming paradigm where the focus is on developing asynchronous and non-blocking components. The core of reactive programming is a data stream that we can observe and react to, and even apply back pressure to as well. This leads to non-blocking execution and better scalability with fewer threads of execution.

Blocking calls in any program often results in critical resources just waiting for things to happen. These include database calls, calls to web services, and file system calls. If we can free up threads of execution from this waiting and provide a mechanism to circle back once results are available, it’ll yield much better resource utilization.

This is what adopting the reactive programming paradigm does for us. While it’s possible to switch over to a reactive library for many of these calls, it may not be possible for everything. For us, fortunately, Spring makes it much easier to use reactive programming with MongoDB and REST APIs.

The four characteristics of a Reactive System are:

  • Responsive: The adoption of the reactive programming paradigm should help us achieve end-to-end non-blocking and, hence, a responsive application.
  • Resilient: Kubernetes deployment with ReplicaSet of the desired number of pods should provide resilience against random failures.
  • Elastic: Kubernetes cluster and resources should provide us the necessary support to be elastic in the face of unpredictable loads.
  • Message-Driven: Having all service-to-service communication handled asynchronously through a Kafka broker should help us here.

Please refer to our blogs for more insightful content and comment if you have any questions regarding the topic.

FOUND THIS USEFUL? SHARE IT

Leave a Reply

Your email address will not be published. Required fields are marked *