-
Motivation
- Reactive streams as extended futures.
- A future (potentially) produces a single value at a single moment in time. The value can be a list, but all the list's elements need to be produced at the same time. However there are activities that produce multiple values, spread over time (e.g.
v_0att_0,v_1att_1,v_2att_2). - A future represents an operation that already started. There isn't anything on the future's interface to start (or restart) a new operation.
- A reactive stream can be viewed as a future that produces more than one value through its lifetime, and whose operation is only triggered when a consumer subscribes to the stream.
- A future (potentially) produces a single value at a single moment in time. The value can be a list, but all the list's elements need to be produced at the same time. However there are activities that produce multiple values, spread over time (e.g.
- Reactive streams as push-style iterables/enumerables.
- On a iterable/enumerable, elements are pulled by consumers (e.g. by calling
nextorMoveNext). If a value is not available, that call will block until the value becomes. Due to this, they aren't a good fit to when the element's availability is spread out through time and threads shouldn't be blocked during those pull operations. - A reactive stream can be viewed as an iterable/enumerable where the source pushes the value to the consumers, instead of consumers pulling the value.
- On a iterable/enumerable, elements are pulled by consumers (e.g. by calling
- Reactive streams as extended futures.
-
The Java 9
Flow.*interfaces and the relation between them.- A
Publisher<T>is a producer ofTitems. - A
Subscriber<T>is a consumer ofTitems. - A
Subscriber<T>can be subscribed (i.e. connected) to aPublisher<T>.- As a consequence, the
Publisher<T>will callSubscriber<T>::obSubscribed, passing in aSubscription. - The
Subscriptionobject can be used by theSubscriber<T>to control its connection to thePublisher<T>, namely:- Cancel the subscription -
cancelmethod. - Request more data to be sent (back-pressure) -
request(long)method.
- Cancel the subscription -
- As a consequence, the
- The data items are pushed to the subscriber via its
onNextmethods. When there is not more data or there was an error, theonCompleteoronErrormethods are called (respectively). - The sequence of methods called on a
SubscriberisonSubscribe onNext* (onError | onComplete)?.
- A
-
Laws
- A
Publisherimplementation as a set of laws, not directly visible in the types, which act as:- Guarantees for the
Publisherconsumer. - Obligations for the
Publisherimplementer. - These laws are described in the reactive streams specification, and include items such as:
- The number of items pushed to a subscriber is less or equal to the number of items requested via the subscription.
- There is a happens-before relation between requesting elements and receiving those elements.
- The
Subscribermethods are called (signalled) serially, meaning that there is a happens-before (HB) relation between those calls.- There is an HB between the
onSubscribeand the firstonNext. - There is an HB between the
onNextwith the n-th item and theonNextwith the (n+1)-th item.
- There is an HB between the
- Guarantees for the
SubscriberandSubscriptionalso have laws.
- A
-
Flow.*vs. RxJava vs. Reactor vs.org.reactivestreams- The
Flow.*interfaces are only available since Java 9. However Java 8 is still very popular and most libraries do support it. - The
Flow.*only has interfaces without any behavior. However, most of the usefulness of reactive streams lays on the operators - ways of combining reactive streams into new reactive streams. Without that, theFlow.*are almost useless. It is similar to Java 8 introducingCompletionStagewithout addingCompletableFuture. org.reactivestreamsprovides interfaces compatible with Java 8. But they are still interfaces; nothing more.- RxJava and Reactor are libraries providing implementations of the
Publisherinterface. More importantly, they provides operators to combine publishers into new publishers. They also provide ways to create publishers. - In this course we will use Reactor, mainly because it is the library used in the Spring eco-system. RxJava provides equivalent functionality.
- The
-
Reactor basics
- The
Fluxclass is Reactor'sPublisherinterface.- Implements the
org.reactivestreams.Publisherinterface (and not theFlow.Publisherinterface because it supports Java 8).
- Implements the
- Provides multiple static factory methods.
- Provides operators as
Fluxinstance methods, allowing for usage as method chaining. Note that since Java doesn't have extension methods, these methods need to belong to the interface.
Flux<Integer> intPublisher = ... Flux<String> stringPublisher = intPublisher.map(i -> i.toString());
- Reactor also provides the
Monoclass, which is a specialization of a Publisher that emits at most one value (it is similar to a future, with subscription capabilities).
- The
-
Simple examples
Flux.justwith a simple subscriber.Flux.createand asynchronous behaviour.- Using a simple function as an unbounded subscriber.
mapoperator.retryoperator.cacheoperator.zipoperator.
-
Threading
- No implicit threading model
- Ability to change the "thread" (i.e. the scheduler) where the subscription and publishing occurs.
- See example using
publishOnandsubscribeOn.
-
HttpClient example with a custom
BodyHandler- See how the
HttpClientuses aSubscriberto handle the response body.
- See how the
-
Backpressure
- ...
- Sinks and associated challenges.
Last active
January 5, 2021 18:03
-
-
Save pmhsfelix/b21450e6b37d1e8f6b51ced9623585a7 to your computer and use it in GitHub Desktop.
Reactive streams short course
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment