With a lot of buzz in the programming world about “reactive Programming”, a new concept following the same path has been introduced. This is “Reactive streams” backed up by the idea of backpressure. In this blog, we try to understand, what does it mean exactly?
What are Reactive Streams?
We are here talking about handling streams of data that needs to be handled in an asynchronous fashion. Also, the most prominent issue is that resource consumption needs to be carefully controlled such that a fast data source does not overwhelm the stream destination.
Reactive streams take care of all these things supported by the idea of Reactive manifesto. So, we can say
“The purpose of Reactive Streams is to provide a standard for asynchronous stream processing with non-blocking backpressure.”
Reactive streams are governed by Reactive Stream Specifications. They are basically set of rules followed created by Pivotal, Netflix, LightBend, Twitter, etc. for defining your reactive streams. The API specifies the types to implement Reactive Streams and achieve interoperability between different implementations. These are specified below:
1. Publisher
It represents the data source like your database, external service, etc.
public interface Publisher<T> { public void subscribe(Subscriber<? super T> s); }
2. Subscriber
It represents the consumer of the stream data.
public interface Subscriber<T> { public void onSubscribe(Subscription s); public void onNext(T t); public void onError(Throwable t); public void onComplete(); }
3. Subscription
A subscription is required to be made by the subscriber against the publisher in order to fetch data.
public interface Subscription { public void request(long n); public void cancel(); }
4. Processor
A Processor represents a processing stage which is both a Subscriber and a Publisher.
public interface Processor<T, R> extends Subscriber<T>, Publisher<R> { }
Understanding the flow:
Data flow between publisher-subscriber
1. Every Flow needs to process events that are published to it by a Publisher instance; the Publisher has one method – subscribe().
2. If any of the subscribers want to receive events published by it, they need to subscribe to the given Publisher.
3. We can think about Subscriber as a Sink. This has four methods that need to be overridden – onSubscribe(), onNext(), onError(), and onComplete().
- onSubscribe() – A subscriber needs to subscribe to the publisher, to actually get data from it.
- onNext() – On every successful item returned by a publisher, we get an onNext() signal.
- onError() – In case of error, an onError() signal is sent to the subscriber from publisher.
- onComplete() – After all the data is successfully transferred, we get an onComplete() signal. We cannot have onComplete() and onError() signal both received. Either our subscription would complete successfully or with an error.
4. If we want to transform the incoming message and pass it further to the next Subscriber, we need to implement the Processor interface. This acts both as a Subscriber because it receives messages, and as the Publisher because it processes those messages and sends them for further processing.
What is backpressure?
Backpressure is something, which gives the capability of controlling the input flow of data to a subscriber with methods such as request() and cancel().
- request() – This allows us to specify, how many items do we actually want from a publisher.
- cancel() – This gives us the capability of canceling the subscription
Backpressure
The push and pull model:
As soon as a subscription is made to a publisher, it starts emitting data (pushing the data). But, with the concept of backpressure, we also know, that a subscriber can also take control of how many items need to be pulled or when a subscription needs to be canceled. So, here we can say, Reactive streams follow the push and pull model.
Reactive Stream is a concept which is being adopted by various java implementations like RxJava, Akka streams, JAVA 9 Flow classes, project reactor used by Spring webflux, etc. We got a conceptual understanding of what are reactive streams and how they actually, work. The implementation will be covered in my upcoming blogs.
I hope, you have liked my blog. If you have any doubt or any suggestions to make please drop a comment. Thanks!
References:
Reactive streams Github