6

I try to figure out Reactor Project and I'm looking for a way to cancel Subscriptions. I know that after making Subscription of for example Flux I can get reference to Cancellation object which can be used to send onCancel Signal, but this is only after making subscription and I need to hold that reference in some kind of Collection.

Is there better way to get Cancellation object? Or just to cancel Subscriptions. Maybe some kind of place which contains reference to all active Subscriptions - yeah that will be awesome...

Kapitalny
  • 651
  • 2
  • 8
  • 17

1 Answers1

8

In Reactor, there is no sense in wanting to cancel a Subscription before you've called subscribe() (as it is that very method that creates the Subscription and propagates that signal up the chain to start the emission of data).

There is no centralized place with all subscriptions, that doesn't make much sense because you'd need a way of finding the specific subscriptions you want to cancel (and keep in mind that each operator in your chain can use an intermediate Subscription as well...).

Note some operators will also cancel subscriptions on your behalf! That is the case for take(int) for instance, which will cancel upstream once enough items have been emitted:

Flux.just(1, 2, 3, 4).log().take(2).subscribe(System.out::println);

will output:

14:17:48.729 [main] INFO  reactor.Flux.Array.1 - | onSubscribe([Synchronous Fuseable] FluxArray.ArraySubscription)
14:17:48.732 [main] INFO  reactor.Flux.Array.1 - | request(unbounded)
14:17:48.732 [main] INFO  reactor.Flux.Array.1 - | onNext(1)
1
14:17:48.732 [main] INFO  reactor.Flux.Array.1 - | onNext(2)
2
14:17:48.732 [main] INFO  reactor.Flux.Array.1 - | cancel()
Simon Baslé
  • 27,105
  • 5
  • 69
  • 70
  • Oh, I didn't know about that operator :O But for me the most important was that Cancellation object was sending OnCancel signal which I could properly deal. But okay I find workaround to my problem - I cancel streams by throwing exceptions into Flux so it isn't bad – Kapitalny Jan 09 '17 at 15:33
  • 2
    I'd advise you to prefer the use of the `Cancellation` object. Note it will become a `Disposable` in 3.1 (at which point you'll have to call `dispose()` rather than `cancel()`). That or look into operators that could naturally match what you want to do, and cancel for you if needed... Throwing exceptions into flux doesn't sound too good of a solution, depending on your use case. – Simon Baslé Jan 09 '17 at 16:38
  • @SimonBaslé I run your code and if the `take(2)` is before `log()` then the `cancel()` signal is not printed. Why? You said the `take` operator cancel the flux, not the source. – Stav Alfi Jan 19 '18 at 15:58
  • 1
    on the contrary, that's exactly what I said : take cancels the upstream, aka the source. log being below, it's downstream not upstream, hence it doesn't see the cancel – Simon Baslé Jan 19 '18 at 18:40