-
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
RxRingBuffer Concurrent Unsubscribe Non-ThreadSafe #1845
Comments
Are you able to reproduce this and can you provide a unit test? Does this also occur with RxJava 1.0.0-rc.10? |
I was able to consistently reproduce this bug with the following: https://gist.github.com/laktech/5bba374f394d12956210 and here is the stack trace for the unit test: https://gist.github.com/laktech/dcac7edb94fde2d037a6 It fails on both 0.20.6 and 1.0.0-rc.10. Succeeds on 0.19.6. |
Thanks. I'll look at this. |
The queue is null on that line, so either it was released before, or the pool didn't provide one at start or there is a visibility issue because it is not volatile. |
Thank you, very helpful. It fails every time for me ... but if I remove Working on this now. |
The code can be fixed by removing the nested private Observable<Integer> keysObservable() {
return Observable.range(0, 10000).flatMap(new Func1<Integer, Observable<Integer>>() {
@Override
public Observable<Integer> call(final Integer t1) {
return Observable.from(listItems(1)).subscribeOn(executorScheduler);
// return Observable.create(new OnSubscribe<Integer>() {
//
// @Override
// public void call(Subscriber<? super Integer> t2) {
// Observable.from(listItems(1)).subscribe(t2);
// }
// }).subscribeOn(executorScheduler);
}
});
} I am still trying to figure out if there is a way to handle the RxRingBuffer issue when it gets unsubscribed prematurely. |
This is going to have to be done in 1.0.x as it's going to take some thought and work. This is an edge case so I'm comfortable continuing with 1.0 as is since this code has spent a couple months being used. @laktech I suggest you adopt the composition approach shown in my previous comment and avoid using I'll come back to this and try to figure out a way for RxRingBuffer to behave safely with concurrent unsubscribe while not killing the performance. |
@benjchristensen Thanks for looking into this. Are there any semantical differences between using |
Semantically no, it will get invoked the same as what is being done via the manual |
Great, thanks for the work-around. |
Reading code again, the So if you want to solve that you could use return Observable.defer(() -> Observable.from(listItems(1))).subscribeOn(executorScheduler); In my test this moves the |
I've tried to fix this but apart from making the NPE go away by reading queue once everywhere and not adding the RxRingBuffer to the InnerSubscription to be unsubscribed, I'm lost. What I would like to do is to call queue.unsubscribe if the inner subscription receives an onError or onCompleted, but due to backpressure, I'm not certain if putting it into drainRequested and drainAll is enough. https://gist.github.com/akarnokd/fc1f2e1946bb39e8794a |
Fixed in 1.0.5. |
rx-java version 0.20.6
The text was updated successfully, but these errors were encountered: