-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Fix teardown issues with synchronous inner-observables #4037
Fix teardown issues with synchronous inner-observables #4037
Conversation
…le when unsubscribed
Thanks for the PR. This looks good. I'll review it tomorrow. |
I recall few places I added checker for return value of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
The places that @kwonoj mentioned where the return value of subscribeToResult
is checked don't appear to be involved in this PR's changes. Rather, those places are referred to in the last paragraph of the OP's PR.
Also, I agree with the OP that whether or not combineLatest
should receive similar treatment is best discussed/implemented elsewhere. That change might be more contentious.
An important PR. Thanks, @peaBerberian |
This PR fixes teardown issues that arised when unsubscribing from an observable emitting values from inner-observable(s) synchronously after subscription, like reported in #4025. An even simpler example is available here.
Basically, the problem is that even after the unsubscription, the inner-observable(s) will continue to run until an asynchronous step is reached.
This was simply because most
OuterSubscriber
s first callsubscribeToResult
on an inner-Observable and THEN callthis.add
on the returned Subscription. This sounds fair, but when we're dealing with an unsubscription happening synchronously after the subscription,this.add
will not have been called yet, and so the teardown will happen without unsubscribing from those inner-observables.A fix has already been brought in 40852ff71, but only for the
MergeMapSubscriber
. In this fix, anInnerSubscriber
is created, registered throughthis.add
and then given as a last argument tosubscribeToResult
, which will use it instead of creating one.It looks like it worked well for
mergeMap
and other related operators for some time now, so I brought the same fix for the followingOuterSubscriber
s (I linked an example showing problematic real use-cases for each of them):I was hesitant to also bring the same fix to other OuterSubscribers with the same problems.
For example, with combineLatest the following code:
outputs:
instead of just:
But here, it's not that problematic, considering that we can just think that every Observable given to a CombineLatest run at the same time (or at least, that's a mental model I have when I'm using it).
Still, code run for nothing there and the code logic looks wrong. What do you think we should do?
The same problematic logic ("adding" the return of a
subscribeToResult
) is also written for many otherOuterSubscriber
s.Namely for the
BufferSubscriber
,BufferToggleSubscriber
,DistinctSubscriber
(for itsflushes
argument, but unsubscribing/erroring from that observable just completes/errors the observable its applied on),ExpandSubscriber
,SwitchFirstSubscriber
,ThrottleSubscriber
,WithLatestFromSubscriber
,WindowSubscriber
andWindowToggleSubscriber
but I did not yet succeed to reproduce a real use-case with any of them where that would be problematic. For this reason, I did not update the logic there.