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: option to fail for using blockingX on the computation scheduler #5020

Merged
merged 3 commits into from
Jan 27, 2017

Conversation

akarnokd
Copy link
Member

@akarnokd akarnokd commented Jan 25, 2017

This PR adds an RxJavaPlugins option failOnNonBlockingScheduler that triggers an IllegalStateException when the user tries to run a blocking method while the execution is on the computation() or single() Scheduler:

Flowable.just(1)
.subscribeOn(Schedulers.computation())
.map(v -> Flowable.just("query").subscribeOn(Schedulers.io()).blockingFirst())
.doOnNext(v -> someAPI(v).subscribeOn(Schedulers.newThread()).blockingSubscribe());
.blockingFirst();

It is an optional setting, default off.

The check is done before going into an await method (and a few other types of blocking). Most blocking operators usually poll the status and try to avoid the actual blocking thus this shouldn't affect synchronous sequences that one extracts a value from.

Detection of a blocking-sensitive scheduler's thread is done by checking the current thread's class for implementing the NonBlockingThread marker interface (currently internal).

The RxThreadFactory has been updated to allow picking a default Thread implementation or a custom one for the newThread(). Note that since #5002 you can create custom schedulers by providing a ThreadFactory.

This works for RxJava's default schedulers but not for AndroidSchedulers.mainThread() where similar blocking should be avoided as well. For them, a plugin-callback action would be more suitable. Question is how that callback should behave (throw, return false, should it be always executed or only when the flag is true).

My proposed solution is to have a plugin callback RxJavaPlugins.setOnBeforeBlocking(BooleanSupplier) that Android users can define the callback for:

RxJavaPlugins.setOnBeforeBlocking(() -> Looper.myLooper() == Looper.getMainLooper())
RxJavaPlugins.setFailOnNonBlockingScheduler(true);

This callback is only executed if the failOnNonBlockingScheduler is set to true.

@akarnokd akarnokd added this to the 2.1 milestone Jan 25, 2017
@akarnokd akarnokd requested a review from JakeWharton January 26, 2017 08:23
@codecov-io
Copy link

Current coverage is 95.67% (diff: 92.45%)

Merging #5020 into 2.x will increase coverage by 0.14%

@@                2.x      #5020   diff @@
==========================================
  Files           609        609          
  Lines         39379      39427    +48   
  Methods           0          0          
  Messages          0          0          
  Branches       6025       6030     +5   
==========================================
+ Hits          37616      37720   +104   
+ Misses          764        734    -30   
+ Partials        999        973    -26   

Powered by Codecov. Last update f53e029...ac942d2

* @since 2.0.5 - experimental
*/
@Experimental
public static void setOnBeforeBlocking(BooleanSupplier handler) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you have a use case in mind for exposing this API in addition to just the boolean?

Copy link
Member Author

Choose a reason for hiding this comment

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

See the updated PR description.

@akarnokd akarnokd merged commit 307f97b into ReactiveX:2.x Jan 27, 2017
@akarnokd akarnokd deleted the BlockingOnComputation branch January 27, 2017 08:08
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.

3 participants