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

1.x: make scan's delayed Producer independent of event serialization #3491

Merged
merged 1 commit into from
Dec 2, 2015

Conversation

akarnokd
Copy link
Member

@akarnokd akarnokd commented Nov 4, 2015

It turns out serializing request() calls with regular onXXX() calls can be problematic because a request() may trigger an emission of events which then end up being queued (since emitting == true). If the request is large and the queue otherwise unbounded, this will likely cause OOME.

In case of scan, the fix was to make the missing request accounting and arrival of the Producer independent of the event's emitter loop; there is no need for them to be serialized in respect to each other.

In case of the ProducerObserverArbiter where the request accounting and producer swapping has to be serialized with the value emission, the solution is to call request() outside the emitter-loop.

There shouldn't be any issue with 2.x scan() because in 2.x, scan receives the Subscription before it allows the downstream to request anything so there is no missing requested to be handled.

This should resolve #3490. As far as I can remember, no other operator should have such problems because all others use ProducerArbiter which is independent of onXXX emission serializations.

It turns out serializing `request()` calls with regular `onXXX()` calls
can be problematic because a `request()` may trigger an emission of
events which then end up being queued (since `emitting == true`). If the
request is large and the queue otherwise unbounded, this will likely
cause OOME.

In case of `scan`, the fix was to make the missing request accounting
and arrival of the `Producer` independent of the event's emitter loop;
there is no need for them to be serialized in respect to each other.

In case of the `ProducerObserverArbiter` where the request accounting
and producer swapping has to be serialized with the value emission, the
solution is to call `request()` outside the emitter-loop.
@akarnokd akarnokd added the Bug label Nov 4, 2015
@akarnokd akarnokd added this to the 1.0.x milestone Nov 4, 2015
@akarnokd akarnokd mentioned this pull request Nov 4, 2015
@davidmoten
Copy link
Collaborator

Can we get this one reviewed and in a release soon please? This is a blocker for me and precludes me using 1.0.15 and 1.0.16. It's a serious bug with scan and I'm nervous for others too that this is out there in another release (1.0.16).

@@ -270,23 +235,51 @@ public void onCompleted() {
emit();
}

@Override
public void request(long n) {

Choose a reason for hiding this comment

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

@akarnokd in the future if its possible to do so could you not rearrange the methods? It makes it so much easier to to read the changes to request side by side instead of seeing one section of code missing entirely only to reappear (modified) later on. Thank you, it's a suggestion to help expedite the PR review process.

Copy link
Member Author

Choose a reason for hiding this comment

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

I did this move out of way so the interleaved view doesn't confuse the reviewer since the original code was simply wrong. This is rarely happening so other PRs will have changes in place.

Choose a reason for hiding this comment

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

Okay thanks for your consideration. As I said it will help a lot for me to be able to see changes interleaved.

@stealthcode
Copy link

Is ProducerObserverArbiter used in the public API? It appears to only be in use in the tests.

@akarnokd
Copy link
Member Author

akarnokd commented Dec 2, 2015

It was added as a tool for building operators but I usually inline the algorithm.

@stealthcode
Copy link

Okay. So it's more like a pattern that gets pasted into operators. Do you usually inline for performance reasons or for custom functionality?

@stealthcode
Copy link

👍

stealthcode pushed a commit that referenced this pull request Dec 2, 2015
1.x: make scan's delayed Producer independent of event serialization
@stealthcode stealthcode merged commit b6d59a4 into ReactiveX:1.x Dec 2, 2015
@akarnokd akarnokd deleted the ScanUnboundedRequestFix1x branch May 18, 2016 22:53
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.

3 participants