0

I've been struggling for a while with what I believe is a pretty basic question.

I have a Flowable which retrieves a bundle of items from the network and emits them.

Flowable
    .create(new FlowableOnSubscribe<Item>() {
        @Override
        public void subscribe(FlowableEmitter<Item> emitter) throws Exception {
            Item item = retrieveNext();

            while (item != null) {
                emitter.onNext(item);

                if (item.isLast) {
                    break;
                }

                item = retrieveNext();
            }

            emitter.onComplete();
        }
    }, BackpressureStrategy.BUFFER)
    .doOnRequest(new LongConsumer() {
        @Override
        public void accept(long t) throws Exception {
            // ...
        }
    });

I need it to work on a per-request basis. That is, I keep a Subscription and call subscription.request(n) when necessary.

The article on Backpressure ("Reactive pull" section) describes Observer's perspective and just briefly mentions that

For [reactive pull] to work, though, Observables A and B must respond correctly to the request() <...> such support is not a requirement for Observables

It does not go into details regarding how such support can in principle be accomplished.

Is there a common pattern for implementing such Observable/Flowable? I didn't find a good example or reference. One poor option I can think of is having a monitor I would lock on inside my while loop when emitter.requested() == 0 and unlock in doOnRequest() from another thread. But this approach just feels cumbersome.

So how is this "slowing down" generally achieved?

Thanks.

SqueezyMo
  • 1,606
  • 2
  • 21
  • 34
  • To clarify, writing operators for 2.x is described [in the wiki](https://github.com/ReactiveX/RxJava/wiki/Writing-operators-for-2.0). – akarnokd Mar 01 '17 at 10:21

1 Answers1

2

Use Flowable.generate:

Flowable.generate(
  () -> generateItemRetriever(),
  (Retriever<Item> retriever, Emitter<Item> emitter) -> {
    Item item = retriever.retrieveNext();
    if(item!=null && !item.isLast()) {
      emitter.onNext(item);
    } else {
      emitter.onComplete();
    }
  }
)

Thgenerated Flowable will be backpressure-aware and unsubscription-aware. If your Retriever has state that needs to be disposed, use the 3-argument generate overload.

However, if you're doing HTTP calls I'd suggest looking into something like Retrofit, which meshes very well with RxJava.

Tassos Bassoukos
  • 16,017
  • 2
  • 36
  • 40