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

Fix request != 0 checking in the scalar paths of merge() #3093

Merged
merged 1 commit into from Jul 20, 2015

Conversation

akarnokd
Copy link
Member

Requested amount could reach zero between the first check and entering the synchronized block where it has to be re-read in order to verify the scalar emission can really happen at that point; the new testMergeAsyncThenObserveOnLoop test failed with MissingBackpressureException after ~20 rounds on my i7 4770K.

This might or might not relate to the canary failure; if combined with retry(), it could have failed over and over, but I'm not sure where the worker retention might have happened.

@akarnokd akarnokd added the Bug label Jul 20, 2015
akarnokd added a commit that referenced this pull request Jul 20, 2015
Fix request != 0 checking in the scalar paths of merge()
@akarnokd akarnokd merged commit 1210182 into ReactiveX:1.x Jul 20, 2015
@akarnokd akarnokd deleted the MergeAsyncTest branch July 20, 2015 21:23
@benjchristensen
Copy link
Member

Is this urgent for release, or can it wait?

@akarnokd
Copy link
Member Author

Yes, this is severe enough, especially if one merges high throughput asynchronous sources before observing them on a scheduler. Synchronous merges or small amount of values won't trigger the MissingBackpressureException.

There is another possible issue which affected the merge() version before. Due to the scalar optimization, it could reorder values from a source:

  1. a value comes in but requested is zero, therefore, the value is queued,
  2. the requested amount increases but it doesn't enter the emission loop yet,
  3. another value comes in, finds the requested to be non-zero, successfully enters the emitting state and emits this second value while the first is still in the queue,
  4. the requester also enters/signals the emitter loop and the queue is drained.

Apparently, users of merge() so far didn't really mind this occasional reordering in the output.

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.

None yet

2 participants