...
- In Project Reactor you have two reactive streams' types at your disposal: Mono which may emit at most 1 element and Flux which may emit 0, finite or infinite number of elements.
- Both of them may end with error. In such situation the stream ends immediately. After stream is terminated (normally or because of error) it won't emit any new elements. You may use retry operators to resubscribe to events in case of error. In cloud environment retryWhen is especially usable: you may use it together with reactor-extra retry functionality in order to support more advanced reaction to unreachable peer microservice.
- If you do not have any background in functional operators like map, flatMap, please take a time to understand them. The general meaning is similar as in Java 8 Streams API. They are the most common operators used in reactive applications. Especially flatMap is very powerful despite its simplicity.
- There is a large group of operators which deal with time dimension of the stream, eg. buffer, window, delay*, timeout etc.
- Be aware that calling aggregation operators (count, collect, etc.) on infinite Flux makes no sense. In worst case scenario you can end JVM with OoM error.
- There is a nice intro to operators in Appendix A of Reactor Documentation. You should also learn how to read Marble Diagrams which concisely describe operators in a graphical form. Fortunately they are quite easy to grasp.
- Do not block in any of handlers which are passed to operators defined by Reactor. The library uses a set of Schedulers (think thread-pools) which are suitable for different jobs. More details can be found in the documentation. If possible try to use non-blocking APIs.
- Most of operators support back-pressure. That means that a demand for new messages will be signalized from downstream subscribers. For instance if you have a
flux.flatMap(this::doThis).map(this::doThat).subscribe()
then ifdoThis
is very slow it will not request many items from sourceflux
and it will emit items at it's own pace fordoThat
to process. So usually there will be no buffering nor blocking needed betweenflux
anddoThis
. - (Almost) nothing will happen without subscribing to the Flux/Mono. These reactive streams are lazy, so the demand will be signaled only when subscription is being made ie. by means of
subscribe
orblock*
methods. - If you are going to go fully-reactive then you should probably not call subscribe/block anywhere in your code. For instance, when using Reactor Netty or Spring Web Flux you should return Mono/Flux from your core methods and it will be subscribed somewhere by the library you are using.
- Return
Mono<Void>
in case you want to return from the method a listener to some processing being done. You may be tempted to returnDisposable
(result ofsubscribe()
) but it won't compose nicely in reactive flow. Usingthen()
operator is generally better as you canflatMap
over it handle onComplete and onError events in the client code.
Handling errors in reactive streams
...