Here at Picnic we are concerned with creating the smoothest and most satisfying online grocery shopping experience for our customers. From a backend perspective this means creating systems that are Resilient, Responsive and Reliable. New features should be easy to implement and satisfy these three R’s from the get-go. Whilst migrating to microservices is a stepping stone to building such a platform, reactive programming is becoming the tool that developers are adopting in the pursuit of responsive, resilient, elastic and message driven services as underlined in the Reactive Manifesto.

Image courtesy of projectreactor.io

There are a number of reactive programming frameworks out in the wild that attempt to address this problem in an elegant manner. At Picnic, we have opted for the Reactive Extensions pattern and opt for RxJava (2.x) and its Spring’s successor; Reactor, given their prevalence in other third party libraries and frameworks, and the extensiveness and fluency of their respective APIs. These are both, in part, implementations of the Reactive Streams API that describes the following simple set of interfaces:

Publisher : a producer of an unbounded number of sequenced elements,

publishing them according to the demand of the Subscriber .

: a producer of an unbounded number of sequenced elements, publishing them according to the demand of the . Subscriber : a consumer of events from the publisher sequence.

: a consumer of events from the publisher sequence. Subscription : represents a one-to-one lifecycle of a Subscriber

subscribing to a Publisher .

: represents a one-to-one lifecycle of a subscribing to a . Processor : a composite of Publisher and Subscriber .

The implementation of Publisher that we are concerned with in RxJava is Flowable<T> . We have opted to use this over Observable<T> as it allows us to be more agnostic to the implementation of reactive streams and also encourages developers to be proactive in handling backpressure.

With these simple yet powerful tools, we are able to compose complex concurrent operations into simple, readable chains of reactive operations.

We currently use RxJava in a number of our backend systems, notably for the parallelisation of purchase order generation — being the orders that we place to our wholesalers — and also in our real-time dashboard platform.

RxJava use case at Picnic

Demand prediction was previously a single-threaded sequential process where demand for products belonging to certain suppliers and certain categories (Order Groups) was calculated sequentially. With RxJava, using just some of the simplest operators we were able to leverage our multicore instances and process these demand prediction tasks in parallel. The ability to concisely express concurrent operations and specify fine-grained thread scheduling eliminates the callback hell traditionally synonymous with writing multithreaded programs in Java.

Before the refactor, our purchase order generation code resembled something like the following:

Here we sequentially stream order groups, generate a purchase order for each insert the results into the repository and return the set to the caller. Without even having to refactor our data sources, and simply wrapping our blocking sources with reactive types, we began to immediately enjoy the benefits of concurrent programming;

Such a small refactor results in the parallel generation of purchase orders on the computation scheduler; the RxJava scheduler whose thread pool size is limited to the number of cores on the machine. Therefore with an 8 core instance we can generate up to 8 purchase orders in parallel. The generated orders are then observed on RxJava’s optimised IO scheduler where we then schedule the repository insertion.

While one can benefit from small refactors of blocking operations into reactive Flowable types, in practise, one should structure their application according to the functional reactive programming paradigm to satisfy the three aforementioned Rs.

Such changes are (in part) replicable using Java 8’s parallel streams;

However, there are a few distinct advantages to the reactive approach. The clearest being the succinctness of the implementation. The second is that while parallelised, this Java streams approach is far from reactive as we must block the calling thread for the execution of the entire chain. Consequently, stream is still pulling, not pushing. Finally, in the RxJava approach, the switching of Schedulers is innately part of stream composition, and as a result we can observe (and in our case, store) the output of the upstream observable as soon as the items are emitted, and on the desired thread pool.

In the remainder of this post we will be touching upon a couple of utilities that we here at Picnic have devised using RxJava on our journey to becoming reactive. We will also take a look at where the Picnic backend is heading with reactive frameworks, using Spring’s latest reactive WebFlux library.