0

I have some Flowables composed using FlowableTransformer like this:

public static FlowableTransformer<I, O> transformer() {
    return f -> {
        return Flowable.mergeArray(5, 5, f.filter(...).map(...), f.filter(...).map(...));
    }
}

The basic use case here is have some form of branching logic - if the elements are A (filter) then do B (map) or if they are C then do D.

However, downstream, when I store the Disposable and later call cancel on it, cancellation only bubbles up the stream as far as the Flowable returned by mergeArray. Upstream of that, i.e. the operators upstream of the call to compose(transformer()), cancellation is never received.

So I thought this was a problem with Flowable.merge() itself (or rather: my lack of understanding), so I changed to using a replay() and a ConnectableFlowable:

public static FlowableTransformer<I, O> transformer() {
    return f -> {
        ConnectableFlowable<TaggedUpdates> cf = taggedUpdateFlowables.replay(5);
        
        Flowable<O> o = f
            .filter(...)
            .map(...)
            .concatWith(
                    cf
                        .filter(...)
                        .map(...)
            );
        
        cf.connect();
        return o;
    };
}

However - the same thing happens. cancellation only bubbles up as far as the ConnectableFlowable.

However, I need to propogate cancellation up the full Flowable so that the source of items stops producing.

Is there a way of doing that? Or should I go about the branching logic in a different way?

Dan Gravell
  • 7,855
  • 7
  • 41
  • 64

1 Answers1

0

Here's how I'm currently working around it. Instead of using a merge or replay I've changed it to just use flatMap:

public static FlowableTransformer<I, O> transformer() {
    return f -> {
        return f
            .flatMap(i -> {
                return Flowable.just(i.items)
                     .filter(...)
                     .map(...)
                     .concatWith(
                         .flatMap(i -> {
                             Flowable.just(i.items)
                                 .filter(...)
                                 .map(...)
                         })
                     );
               });
    };
}

However, I'm a bit worried later I'll not be able to do this workaround where I do need to use replay, e.g. where computation of the upstream is expensive.

Dan Gravell
  • 7,855
  • 7
  • 41
  • 64