2.x: Evaluate Schedule initialization via Callable#4585
2.x: Evaluate Schedule initialization via Callable#4585akarnokd merged 13 commits intoReactiveX:2.xfrom peter-tackage:fix/lazy-init-schedulers
Conversation
| } | ||
|
|
||
| /** | ||
| * Wraps the call to the callable in try-catch and propagates thrown |
| * @return the value returned by the hook | ||
| */ | ||
| public static Scheduler initComputationScheduler(Scheduler defaultScheduler) { | ||
| public static Scheduler initComputationScheduler(Callable<Scheduler> defaultScheduler) { |
There was a problem hiding this comment.
Should not it throw on a null callable? What's the point of calling with null?
There was a problem hiding this comment.
This was done for consistency with the existing expectations in RxJavaPluginsTest.clearIsPassthrough(), specifically:
assertNull(RxJavaPlugins.initComputationScheduler(null));
assertNull(RxJavaPlugins.initIoScheduler(null));
assertNull(RxJavaPlugins.initNewThreadScheduler(null));
assertNull(RxJavaPlugins.initSingleScheduler(null));Should this be changed to only return null if the Callable returns null (and throw if the Callable itself is null)?
There was a problem hiding this comment.
Null should not be allowed as a return value from the Callable nor from the init Function.
There was a problem hiding this comment.
This would be a change, because previously the Scheduler value for RxJavaPlugins.init* was allowed to be null, as per - assertNull(RxJavaPlugins.initSingleScheduler(null));.
I will add an additional set of tests for the new behavior (something along the lines of assemblyHookCrashes).
| * @param t the callable, not null (not verified) | ||
| * @return the result of the callable call | ||
| */ | ||
| static <T> T call(Callable<T> t) { |
There was a problem hiding this comment.
Not sure what you mean. I've tried to be consistent with the abstraction of the similar apply method. Do you think that should change?
Current coverage is 78.17% (diff: 88.88%)@@ 2.x #4585 diff @@
==========================================
Files 552 552
Lines 36184 36297 +113
Methods 0 0
Messages 0 0
Branches 5584 5602 +18
==========================================
+ Hits 28255 28375 +120
+ Misses 5917 5912 -5
+ Partials 2012 2010 -2
|
| * @return the callable result if the callable is nonnull, null otherwise. | ||
| */ | ||
| static <T> T callOrNull(Callable<T> t) { | ||
| return t == null ? null : call(t); |
There was a problem hiding this comment.
null should never be allowed
| * @throws NullPointerException if the callable returns null | ||
| */ | ||
| static <T, R> R apply(Function<T, R> f, Callable<T> t) { | ||
| try { |
There was a problem hiding this comment.
I think you mean to check value here instead of t
There was a problem hiding this comment.
Also you could just T value = Object.requireNonNull(t.call(), "messge")
There was a problem hiding this comment.
Yep, good find.
There was a problem hiding this comment.
Yes, that would be better. I didn't notice the return value in the signature.
| SINGLE = RxJavaPlugins.initSingleScheduler(new Callable<Scheduler>() { | ||
| @Override | ||
| public Scheduler call() throws Exception { | ||
| return new SingleScheduler(); |
There was a problem hiding this comment.
Just in case call() is called multiple times by the hook, these could actually return an field of an inner class (singleton holder pattern or what's the name):
static final class SingleHolder {
static final Scheduler DEFAULT = new SingleScheduler();
}
SINGLE = RxJavaPlugins.initiSingleScheduler(new Callable<Scheduler>() {
@Override
public Scheduler call() {
return SingleHolder.DEFAULT;
}
});|
@akarnokd, Correct me if I'm wrong, but in order to avoid the evaluation of the default Scheduler instance when it is being overridden, I still need to change the Otherwise the invocation of |
|
Yes, you still need |
|
I've added the remaining lazy initialization. I've also fairly aggressively enforced non-null in the associated functions, for example: public static Scheduler initIoScheduler(Callable<Scheduler> defaultScheduler) {
ObjectHelper.requireNonNull(defaultScheduler, "Scheduler Callable can't be null");
Callable<Scheduler>, Scheduler> f = onInitIoHandler;
if (f == null) {
return callRequireNonNull(defaultScheduler);
}
return applyRequireNonNull(f, defaultScheduler);
}However, to me, this seems slightly out of place / over the top. Is that enforcement necessary or should the resultant null Scheduler be left unasserted and left to the eventual NullPointerException when the Scheduler is used? Either way, I'm happy to keep or remove that based upon review feedback. |
|
Aggressive input validation is never over the top. If you defer checking On Sun, Sep 25, 2016, 7:09 AM Peter Tackage notifications@github.com
|
|
@akarnokd, all done as far as I am concerned. Do I need to anything else for this to be merged? |
|
I was waiting for you to settle with the implementation. Thanks for the contribution. |
This implements the solution proposed in #4572 - to initialize the Schedulers via a Callable, rather than directly via a value.