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

switchIfEmpty - fix backpressure bug and lost requests #2996

Merged
merged 1 commit into from
Jun 1, 2015

Conversation

davidmoten
Copy link
Collaborator

OperatorSwitchIfEmpty suffered from these conditions:

  • Backpressure was not enabled for the source observable (as opposed to the altenate) because setProducer called super.setProducer instead of child.setProducer
  • Requests could be lost

Bot the of the above problems are solved by using ProducerArbiter from @akarnokd.

Included two unit tests that failed on previous code.

@davidmoten davidmoten changed the title Operator switchIfEmpty - fix backpressure bug and lost requests switchIfEmpty - fix backpressure bug and lost requests May 31, 2015
@@ -38,33 +38,35 @@ public OperatorSwitchIfEmpty(Observable<? extends T> alternate) {
final SwitchIfEmptySubscriber parent = new SwitchIfEmptySubscriber(child, ssub);
ssub.set(parent);
child.add(ssub);
child.setProducer(new Producer() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd instantiate the ProducerArbiter before parent and supply it to SwitchIfEmptySubscriber and child, saving on this 'relaying' allocation. (Remark, our life would be much easier if we could implement Producer in Subscriber, but since request() is protected final, it is unoverridable :( )

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah life would be easier if request() was public. I wouldn't mind seeing it opened up, do you think it worth discussing in an issue?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's too late for that. We will be careful in RxJava 2.0.

@akarnokd akarnokd added the Bug label May 31, 2015
@davidmoten davidmoten force-pushed the switch-if-empty-request-bug branch from 0202597 to 4f7926e Compare June 1, 2015 00:57
@davidmoten
Copy link
Collaborator Author

Made those changes, ta.

@davidmoten davidmoten force-pushed the switch-if-empty-request-bug branch from 4f7926e to c0309f0 Compare June 1, 2015 01:41
@davidmoten
Copy link
Collaborator Author

Cleaned up a bit, made the parent subscriber class a static class and improved names

child.onNext(t);
}
}));
ssub.set(alternate.unsafeSubscribe(new AlternateSubscriber<T>(child, arbiter)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead:

AlternateSubscriber<T> as = new AlternateSubscriber<T>(child, arbiter);
ssub.set(as);
alternate.unsafeSubscribe(as);

@davidmoten davidmoten force-pushed the switch-if-empty-request-bug branch from c0309f0 to 81f575c Compare June 1, 2015 07:25
@davidmoten
Copy link
Collaborator Author

Well spotted, thanks. Updated.

@Override
public void onNext(T t) {
child.onNext(t);
arbiter.produced(1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this produced(1) is unnecessary: sure the arbiter's value will grow indefinitely, but there won't be any further setProducer on it thus conserving the requested/delivered amount is less important.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hey-you-delivered-more-than-requested check is useful though

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, you need to add this to the other child.onNext() call as well.

@davidmoten davidmoten force-pushed the switch-if-empty-request-bug branch from 81f575c to c4fcd91 Compare June 1, 2015 10:06
@davidmoten
Copy link
Collaborator Author

Erk, thanks for noticing that. Updated.

@akarnokd
Copy link
Member

akarnokd commented Jun 1, 2015

Great, thanks!

akarnokd added a commit that referenced this pull request Jun 1, 2015
switchIfEmpty - fix backpressure bug and lost requests
@akarnokd akarnokd merged commit 53a0204 into ReactiveX:1.x Jun 1, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants