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

2.x: make sure interval+trampoline can be stopped #5367

Merged
merged 1 commit into from May 28, 2017

Conversation

akarnokd
Copy link
Member

This PR fixes the case where a trampoline scheduler is used with the interval or intervalRange operator, the periodic emissions can't be cancelled properly. The synchronous and blocking nature of the periodic schedule is that the Disposable is never connected with the downstream and the interval stays in a drain-sleep loop per emission indefinitely.

This PR changes the operators to use the Worker of a trampoline scheduler that is available before the drain-sleep loop thus a downstream cancellation can stop the loop. Any other "async" scheduler will still use the direct periodic scheduling facility.

In addition, the trampoline loop has been fixed to check for the worker disposed state in the inner loop.

@codecov
Copy link

codecov bot commented May 25, 2017

Codecov Report

Merging #5367 into 2.x will decrease coverage by 0.01%.
The diff coverage is 100%.

Impacted file tree graph

@@             Coverage Diff              @@
##                2.x    #5367      +/-   ##
============================================
- Coverage     96.16%   96.14%   -0.02%     
- Complexity     5780     5782       +2     
============================================
  Files           630      630              
  Lines         41162    41189      +27     
  Branches       5721     5726       +5     
============================================
+ Hits          39582    39603      +21     
+ Misses          625      621       -4     
- Partials        955      965      +10
Impacted Files Coverage Δ Complexity Δ
...rnal/operators/flowable/FlowableIntervalRange.java 95.91% <100%> (+0.56%) 3 <0> (+1) ⬆️
...tivex/internal/schedulers/TrampolineScheduler.java 94.93% <100%> (+0.19%) 6 <0> (ø) ⬇️
...ernal/operators/observable/ObservableInterval.java 96.42% <100%> (+0.97%) 3 <0> (+1) ⬆️
.../internal/operators/flowable/FlowableInterval.java 94.44% <100%> (+1.11%) 3 <0> (+1) ⬆️
.../operators/observable/ObservableIntervalRange.java 97.36% <100%> (+0.49%) 3 <0> (+1) ⬆️
...internal/operators/completable/CompletableAmb.java 94.91% <0%> (-5.09%) 10% <0%> (-1%)
...rnal/subscriptions/DeferredScalarSubscription.java 93.84% <0%> (-4.62%) 27% <0%> (-1%)
...erators/completable/CompletableConcatIterable.java 95.91% <0%> (-4.09%) 2% <0%> (ø)
...rnal/operators/completable/CompletableTimeout.java 94% <0%> (-4%) 2% <0%> (ø)
...reactivex/internal/operators/single/SingleAmb.java 96.36% <0%> (-3.64%) 9% <0%> (-1%)
... and 43 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c799bc0...80efeb4. Read the comment docs.


is.setResource(d);
if (sch instanceof TrampolineScheduler) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can't this fix be made in TrampolineScheduler itself?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, because the schedulePeriodic has to return a Disposable in order to allow it to be stopped but the first task stays in the trampoline loop and stays there never returning from the call. The disposability has to happen before that. This is a similar case to synchronous cancellation with streams that have to send a Disposable/Subscription first to allow cancellation before going into some form of loop that would otherwise not return. The classic Rx.NET and early RxJava suffered from this on a grand scale. This issue only affects interval and trampoline scheduler together.

@artem-zinnatullin
Copy link
Contributor

artem-zinnatullin commented May 25, 2017 via email

@akarnokd
Copy link
Member Author

akarnokd commented May 25, 2017

Yeah I see, so alternative solution would be to accept Disposable as
parameter instead of returning it in scheduleX() methods right?

No, it would require a consumer callback to be called, similar to how autoConnect or connect has one, to get the Disposable out before it gets submitted to an executor.

I'm on mobile, but I believe Scheduler is still abstract class as in 1.x
and such overloads could probably be added without breaking compatibility?

Doesn't work. In order to not break existing custom schedulers, the new non-abstract methods have to call the old ones which return Disposable instead of providing it some way before.

@artem-zinnatullin
Copy link
Contributor

artem-zinnatullin commented May 25, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants