Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Any/All should not unsubscribe downstream. #1938

Merged
merged 2 commits into from
Dec 13, 2014

Conversation

akarnokd
Copy link
Member

@akarnokd akarnokd commented Dec 8, 2014

Should fix issue #1935

When in doubt, see take.

@myinsiders
Copy link

Thanks, I'll give this a go and verify it fixes it for me.

Others that look like they may be susceptible:

OperatorAll
DebounceWithSelector
OperatorSkipTimed
OperatorSkipUntil

@akarnokd
Copy link
Member Author

akarnokd commented Dec 8, 2014

Thanks for the other cases. I'll add the fixes for them in this PR.

@akarnokd
Copy link
Member Author

akarnokd commented Dec 8, 2014

I find DebounceWithSelector, OperatorSkipTimed and OperatorSkipUntil suspicious, but since these don't just return a single value, I don't know what effect it has on backpressure if I break the chain the way Any or All does.

While we are at it, I think Any and All should request(Long.MAX_VALUE) regardless of the downstream because they spin on a single flag and thus can handle any throughput. The current version request 1-by-1 which adds large overhead.

@akarnokd akarnokd changed the title Any should not unsubscribe downstream. Any/All should not unsubscribe downstream. Dec 8, 2014
@benjchristensen
Copy link
Member

I think Any and All should request(Long.MAX_VALUE) regardless of the downstream because they spin on a single flag and thus can handle any throughput

Agreed.

since these don't just return a single value, I don't know what effect it has on backpressure if I break the chain the way Any or All does

We would have to manually compose through the backpressure if we break the chain. Why though should we need to decouple on those as they shouldn't need to unsubscribe early? If we are we probably shouldn't be. Having them chained is far more efficient so we don't want to break the chain if we don't need to.

@akarnokd
Copy link
Member Author

akarnokd commented Dec 9, 2014

We would have to manually compose through the backpressure if we break the chain. Why though should we need to decouple on those as they shouldn't need to unsubscribe early? If we are we probably shouldn't be. Having them chained is far more efficient so we don't want to break the chain if we don't need to.

They unsubscribe themselves in onCompleted() and onError() and may prevent the async use of the preceding onNext(). In other words, if I manually schedule a task for each onNext event and add the cancellation subscription to the downstream subscriber, the onCompleted() in these operators will cancel that task. (ObserveOn was fixed a couple of times to make this not a problem.)

@benjchristensen
Copy link
Member

But why do they need to unsubscribe in onComplete and onError? Those are terminal events, we shouldn't need to unsubscribe as that will happen automatically after the terminal event is emitted.

@akarnokd
Copy link
Member Author

akarnokd commented Dec 9, 2014

Because they need to terminate a companion observable or timer when the main terminates.

@benjchristensen
Copy link
Member

I know they need to cleanup, but why does it need to happen eagerly right then? The contract is that after it emits onError or onComplete it will eventually be unsubscribed after all downstream work is done. So why do we need to call unsubscribe eagerly? If I remove those unsubscribe calls no tests break, and unsubscribe will still end up being called.

For all three it seems there is no need to be eager as these do not terminate their origin early. Cleanup of their companion Observable can happen eager if they want (such as SkipUntil) but that is not part of the chain nor does it require unsubscribing the entire operator.

benjchristensen added a commit that referenced this pull request Dec 13, 2014
Any/All should not unsubscribe downstream.
@benjchristensen benjchristensen merged commit 162e042 into ReactiveX:1.x Dec 13, 2014
@benjchristensen
Copy link
Member

Merging as this PR is fine, the discussion is about other things.

@akarnokd akarnokd deleted the OperatorAnyFix branch January 20, 2015 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants