So far, we’ve become very familiar with the push-based nature of RxJava. Events are produced somewhere up in the stream to be consumed later by all subscribers. We never really paid much attention to what happens if Observer is slow and cannot keep up with events emitted from within
Observable.create(). This entire chapter is devoted to this problem.
RxJava has two ways of dealing with producers being more active than subscribers:
- Various flow-control mechanisms such as sampling and batching are implemented via built-in operators
- Subscribers can propagate their demand and request only as many items as they can process by using a feedback channel known as backpressure
Before RxJava began implementing backpressure (see the section “Backpressure”), dealing with producers (
Observables) outperforming consumers (
Observers) was a difficult task. There are quite a few operators that were invented to deal with producers pushing too many events, and most of them are quite interesting on their own. Some are useful for batching events; others are dropping some events. This section walks you through these operators, including some examples.
There are cases for which you definitely want to receive and process every single event pushed from the upstream
Observable. But, there are some scenarios for which periodic sampling is enough. The most obvious case is receiving measurements from some device; for example, temperature. The frequency at which the device produces new measurements is often irrelevant for us, especially when the measurements appear often but are very similar to one another. The
sample() operator looks at the upstream
Observable periodically (for example, every second) and emits the last encountered event. If there were no event at all in the last one-second period, no sample is forwarded downstream and the next sample will be taken after one second, as illustrated in this sample: