How it works...

Highlighted in this recipe are two of the most important Reactive Streams interfaces, Publisher and Subscriber. These main APIs impact the interactive and Reactive model of data Stream emission from the data provider to the recipient component. The main goal of these interfaces is to implement the flow of the data objects during emission and also to provide the other to programming languages or web frameworks the opportunity to custom implement the Reactive specification depending on the purpose.

The blueprint of the Publisher interface is implemented using the following template:

public interface Publisher<T> { 
  public void subscribe(Subscriber<? super T> s); 
} 

Here, T is the type of Stream object and subscribe() is the way Subscriber<T> connects to live data Stream emissions. There is no other way of executing all the Publisher<T> events but to connect to subscriber(s).

Moreover, a publisher can be composed of blocking and non-blocking operators that can be executed asynchronously to process a Stream of elements. For instance, the getValidEmployees() method extracts a Stream of the Employee objects through fromIterable() that becomes the observable or subject for the subscribers to listen to. While generating the stream, another Stream function, map() is executed side-by-side with fromIterable() to convert each Stream object to another form creating a separate stream. Thus, if there are other additional operators in the event, there will be levels of independent, threaded Streams that will be working asynchronously to formulate the final data emission:

Whenever a Throwable is encountered by any of the Stream layers, the risky layer of operator(s) in the preceding diagram will just execute its onError() operator in order for Publisher<T> to exit as if nothing happens. In normal non-asynchronous cases, two or more methods can be executed sequentially, one after the other which might not be good whenever server-side exceptions or slow database connections occur (such as starvation or degradation of resources). Tightly-coupled processes will always replicate more problems in an application.

On the other hand, a Subscriber interface is designed to contain the following template:

public interface Subscriber<T> { 
  public void onSubscribe(Subscription s); 
  public void onNext(T t); 
  public void onError(Throwable t); 
  public void onComplete(); 
} 

Here, onComplete() is the method that will be signaled to execute after a successful data emission; onError() is the operator triggered when Throwable is encountered during the Publisher event execution; onNext() is the method that retrieves each Stream object; and lastly onSubscribe(), which bears the very essential Subscription interface that has a request() method is used to control the number of data objects fired in each transmission. There is no guarantee that a subscriber will always get the same Stream provided by publishers in its previous emissions. Also, the final Stream can contain a single-entity (Mono<T>) or a list of data (Flux<T>).

Stream operators in publishers are quite similar to threaded operators in the Stream pipeline of java.util.stream.Stream presented in Chapter 6, Functional Programming. Some of the operators require a functional interface implemented using Lambda expressions just like in the recipes. Some require a transaction to be thread-ready through wrapping it with a Callable object. Thus, we can conclude that Reactor Core 3.x supports functional Reactive programming using the Java 1.8 APIs of java.util.function.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.212.217