Reactive Programming - Implementations of the specification in Java

Reactive Programming - Implementations of the specification in Java

How does a programmer implement reactive programming in Java?

Reactive Streams specification

In Java, reactive programming is achieved through the use of Reactive Streams. Reactive Stream is a specification that defines a collection of interfaces and classes for building reactive applications. Thanks to this standard, several libraries and frameworks have been developed in Java to implement the Reactive Streams specification, including RxJava, Project Reactor, and Akka. These libraries provide developers with APIs for writing reactive code and creating reactive applications that are both scalable and responsive.

Reactive Streams is an initiative to provide a standard for asynchronous stream processing with non-blocking back pressure.

It is a design approach that uses asynchronous programming to manage real-time updates to content.

  1. https://www.reactive-streams.org/
  2. https://github.com/reactive-streams/reactive-streams-jvm/blob/v1.0.4/README.md
  3. https://github.com/reactive-streams/reactive-streams-jvm

Participants in the Reactive Streams Specification

Reactive Streams specification introduces four interfaces that should be used and overridden when creating a reactive stream.

https://www.reactive-streams.org/reactive-streams-1.0.4-javadoc/org/reactivestreams/package-summary.html

  1. Publisher interface
    1. package org.reactivestreams;
      
      public interface Publisher<T> {
          void subscribe(Subscriber<? super T> var1);
      }
      
    2. Used to register the subscriber to the publisher.
    3. The subscribe method of this interface accepts the subscriber object and registers it.
  2. Subscriber interface
    1. package org.reactivestreams;
      
      public interface Subscriber<T> {
          void onSubscribe(Subscription var1);
      
          void onNext(T var1);
      
          void onError(Throwable var1);
      
          void onComplete();
      }
      
    2. void onSubscribe​(Subscription s) -
      1. Will be called by the publisher when subscribing to the Subscribe object.
      2. Invoked after calling Publisher.subscribe(Subscriber).
    3. void onNext​(T t) -
      1. Will be called when the next data will be published to the subscriber.
      2. Data notification sent by the Publisher in response to requests to Subscription.request(long).
    4. void onError​(java.lang.Throwable t) -
      1. Will be called when exceptions arise while publishing data to the subscriber
      2. Failed terminal state.
    5. void onComplete() -
      1. Will be called after the successful completion of data publishing to the subscriber
      2. Successful terminal state.
  3. Subscription interface
    1. package org.reactivestreams;
      
      public interface Subscription {
          void request(long var1);
      
          void cancel();
      }
      
    2. The subscription object will be created when the user subscribes to the publisher.
    3. The subscription object will be passed to the subscriber object via the subscriber’s onSubscribe method.
    4. void request​(long n) - No events will be sent by a Publisher until demand is signaled via this method.
    5. void cancel() - Request the Publisher to stop sending data and clean up resources.
  4. Processor interface
    1. package org.reactivestreams;
      
      public interface Processor<T, R> extends Subscriber<T>, Publisher<R> {
      }
      
    2. inherits the methods from both Publisher and Subscriber interfaces

Publisher Subscriber communication in Reactive Streams Specification

  1. We pass a Subscriber instance to the Publisher using the Publisher's subscribe() method - to get updates.
  2. The Publisher gives a Subscription object to the Subscriber.
    void	onSubscribe​(Subscription s) - Invoked after calling Publisher.subscribe(Subscriber).
    
  3. The relationship between the Publisher and the Subscriber is now established through the Subscription object.
    1. The Subscriber can talk to the Publisher using the Subscription object.
    2. The Subscriber can request() updates.
    3. The Subscriber can cancel() updates.
  4. The Subscriber uses the request() method to get updates from the Publisher.
  5. The Publisher uses the onNext() method of the Subscriber to pass items to the Subscriber. The Publisher will only give the requested number of items. Not more.
  6. When the Publisher is done sending items to the Subscriber or when there are no more items to be sent to the Subscriber, the Publisher will call the Subcriber's onComplete() method. Publisher will NOT send anything to the Subscriber after onComplete(). After this, the Subscription object will no longer work.
  7. When there is an error in the Publisher while it is trying to send items to the Subscriber, the Publisher will call the Subcriber's onError() method. Publisher will NOT send anything to the Subscriber after onError(). After this, the Subscription object will no longer work.

Libraries and frameworks

All of these libraries have implementation of Java’s Reactive Streams specification interfaces.

  1. Akka streams
    1. Akka is a framework and runtime for building high-concurrency, distributed, fault-tolerant applications. Akka supports reactive programming by using the Actor model for concurrency,
    2. The Akka framework supports the development of reactive applications using a wide range of programming models, from functional to declarative and imperative programming. The Akka framework supports Java and Scala for building reactive applications.
  2. RxJava
    1. RxJava is a popular Reactive library for Android developers. It’s known as the “go-to” framework for making it easier to handle concurrency and asynchronous tasks that come with mobile programming. RxJava is an open-source Functional Reactive Programming (FRP) library for Android. It adds a layer of abstraction over threading to ease the implementation of complex concurrent behavior.
    2. This is a series of posts: https://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/
    3. https://www.baeldung.com/rx-java
    4. https://www.baeldung.com/rxjava-backpressure
    5. https://abhiappmobiledeveloper.medium.com/rxjava-operators-understanding-map-flatmap-switchmap-and-concatmap-d88633f83b32
  3. Reactive Programming - Project Reactor (support from Spring team)
  4. Spring Framework 5.0
    1. Spring Framework 5 uses Reactive streams as a way to communicate backpressure between asynchronous components and libraries in the framework. This is a specification that has been developed through industry collaboration and is also used in Java 9. The Spring Framework already supports Reactor internally, but now it’s using Reactor to extend it even more. For developers who are already familiar with Spring, it builds on Reactor and offers a similar programming model.

TODO

  1. https://www.reddit.com/r/java/comments/fxejpo/reactor_vs_rxjava3_2020_edition/

Links to this note