-
Notifications
You must be signed in to change notification settings - Fork 7.6k
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
publish().refCount() race may leave observers hanging #6501
Comments
In our anecdotal case, it's an observable that gets disposed and therefore cancels the HTTP request, while the next subscriber receives the immediately-canceled stream from the first subscriber. Something like:
Subscriber 1 for one reason or another, disposes before the API request responds. Nearly the same time as the first one disposing, Subscriber 2 subscribes, and only receives the InterruptedIOException from the first request being canceled. As I understood, when the first subscriber disposes, it should cancel the API request and also removes itself as a subscriber, so the refCount() should cause the upstream observable to dispose. When the 2nd subscriber attaches, it should be starting a brand new request to the upstream API source, rather than receiving the first error. So it's slightly different because it's not actually a timeout (as if the stream had zero events), it's actually receiving the error from the first subscriber's canceled attempt. |
We were able to track down the part of our code that was triggering this issue, but I still believe that it is a race condition in In our case (Android), we had 2 separate Fragments being added approximately simultaneously. Fragment 1 makes a request for configuration (which is implemented with As a result of CompositeDisposable.clear(), Fragment 1's config request got disposed, and rather than allowing Fragment 2's request to continue operating due to the refCount, Fragment 2 only receives the OkHttp InterruptedIOException from the canceled operation and never receives a completed successful response. |
share() is generally tricky, even without this bug, because people have a sense of it staying alive a bit longer and also receiving onNext events in time, which is not guaranteed with it. You could try using |
This is a tough one. What happens is that the termination happens when a new observer subscribes, which makes This could be resolved if a late observer wasn't assigned to a fresh publishing instance, but receive the terminal signal instead (thus making refCount get down to zero and reset/reconnect). Unfortunately, this is a behavior change that, in addition, requires API change to allow manual resetting for those who work with I'll keep thinking about this problem, until then, you could use the workarounds above, or use |
I tried using I don't think I tried |
This test eventually times out because one of the sources will not complete or trigger a reconnection:
(Originally reported as a comment.)
The text was updated successfully, but these errors were encountered: