0

The documentation of Subscription#cancel says that

Data may still be sent to meet previously signalled demand after calling cancel.

  1. In which scenario would people expect the publisher to continue to send till previous signalled demand is met?
  2. Also, if I don't want any new items to be sent after cancellation, what should I do?
Ashok Koyi
  • 5,327
  • 8
  • 41
  • 50

1 Answers1

1

Unless you are creating low level operators or Publishers, you don't have to worry about this.

In which scenario would people expect the publisher to continue to send till previous signalled demand is met?

None of the mainstream Reactive Streams libraries do that as they stop sending items eventually. RxJava 2 and Reactor 3 are pretty eager on this so you'd most likely have an extra item on a low-lever asynchronously issued cancellation. Akka Stream may signal more than that (last time I checked, they mix control and item signals and there is a configuration setting for max synchronous items per stream that can lead to multiple items being emitted before the cancellation takes effect).

Also, if I don't want any new items to be sent after cancellation, what should I do?

Depends on what you implement: a Publisher or a Subscriber.

In a Publisher the most eager method is to set a volatile boolean cancelled field and check that every time you are in some kind of emission loop.

In a Subscriber, you can have a boolean done field that is checked in each onXXX so that when you call Subscription.cancel() from onNext, any subsequent call will be ignored.

akarnokd
  • 69,132
  • 14
  • 157
  • 192
  • 1. Since the subscriber can be invoked on any thread, shouldn't the done field too be `volatile`? 2. In the subscriber case, when the subscription is cancelled, I dont see anyone setting `done` field. Am I missing something in this example? – Ashok Koyi Apr 28 '18 at 09:21
  • 1
    I said when cancel is invoked from within onNext. If you allow external cancellation, you have to use volatile. – akarnokd Apr 28 '18 at 10:05
  • I'm referring to this. This calss is allowing external cancellation, but not done is not volatile & is never set. Plz clarify https://github.com/ReactiveX/RxJava/blob/be12fe2ff996cf5744b87705555c40bb769fd125/src/main/java/io/reactivex/internal/operators/flowable/FlowableTake.java#L102 – Ashok Koyi Apr 28 '18 at 12:53
  • 1
    It is set on [L83](https://github.com/ReactiveX/RxJava/blob/be12fe2ff996cf5744b87705555c40bb769fd125/src/main/java/io/reactivex/internal/operators/flowable/FlowableTake.java#L83). Plus, the operator itself is not some sort of generator so it passes the cancellation signal upstream as there is no direct benefit of eagerly checking a cancelled status in 1-to-1 operators. – akarnokd Apr 28 '18 at 13:12
  • Is it fair to say as a rule of thumb (not for all operators ofcourse), a custom operator should delegate all the cancellations to the upstream `Publisher` & pass the elements downstream even if cancellation already happened earlier? – Ashok Koyi Apr 28 '18 at 13:23
  • 1
    It depends on what the custom operator does. If there is an item amplification or asnyc boundary, you should act on cancellation directly and do your best to prevent signalling the downstream. – akarnokd Apr 28 '18 at 13:30
  • Thanks a lot for your help – Ashok Koyi Apr 28 '18 at 13:35