-
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_0
att_0
,v_1
att_1
,v_2
att_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
next
orMoveNext
). 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 ofT
items. - A
Subscriber<T>
is a consumer ofT
items. - 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
Subscription
object can be used by theSubscriber<T>
to control its connection to thePublisher<T>
, namely:- Cancel the subscription -
cancel
method. - 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
onNext
methods. When there is not more data or there was an error, theonComplete
oronError
methods are called (respectively). - The sequence of methods called on a
Subscriber
isonSubscribe onNext* (onError | onComplete)?
.
- A
-
Laws
- A
Publisher
implementation as a set of laws, not directly visible in the types, which act as:- Guarantees for the
Publisher
consumer. - Obligations for the
Publisher
implementer. - 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
Subscriber
methods are called (signalled) serially, meaning that there is a happens-before (HB) relation between those calls.- There is an HB between the
onSubscribe
and the firstonNext
. - There is an HB between the
onNext
with the n-th item and theonNext
with the (n+1)-th item.
- There is an HB between the
- Guarantees for the
Subscriber
andSubscription
also 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 introducingCompletionStage
without addingCompletableFuture
. org.reactivestreams
provides interfaces compatible with Java 8. But they are still interfaces; nothing more.- RxJava and Reactor are libraries providing implementations of the
Publisher
interface. 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
Flux
class is Reactor'sPublisher
interface.- Implements the
org.reactivestreams.Publisher
interface (and not theFlow.Publisher
interface because it supports Java 8).
- Implements the
- Provides multiple static factory methods.
- Provides operators as
Flux
instance 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
Mono
class, 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.just
with a simple subscriber.Flux.create
and asynchronous behaviour.- Using a simple function as an unbounded subscriber.
map
operator.retry
operator.cache
operator.zip
operator.
-
Threading
- No implicit threading model
- Ability to change the "thread" (i.e. the scheduler) where the subscription and publishing occurs.
- See example using
publishOn
andsubscribeOn
.
-
HttpClient example with a custom
BodyHandler
- See how the
HttpClient
uses aSubscriber
to 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