Skip to content

Commit 55b1e25

Browse files
committed
Add Schedulers.reset() for better testing
Resolves ReactiveX#3985
1 parent 6004156 commit 55b1e25

File tree

2 files changed

+83
-8
lines changed

2 files changed

+83
-8
lines changed

src/main/java/rx/schedulers/Schedulers.java

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616
package rx.schedulers;
1717

1818
import rx.Scheduler;
19-
import rx.internal.schedulers.*;
19+
import rx.annotations.Experimental;
20+
import rx.internal.schedulers.ExecutorScheduler;
21+
import rx.internal.schedulers.GenericScheduledExecutorService;
22+
import rx.internal.schedulers.SchedulerLifecycle;
2023
import rx.internal.util.RxRingBuffer;
2124
import rx.plugins.RxJavaPlugins;
2225
import rx.plugins.RxJavaSchedulersHook;
@@ -32,7 +35,14 @@ public final class Schedulers {
3235
private final Scheduler ioScheduler;
3336
private final Scheduler newThreadScheduler;
3437

35-
private static final Schedulers INSTANCE = new Schedulers();
38+
private static Schedulers INSTANCE;
39+
40+
private static synchronized Schedulers getInstance() {
41+
if (INSTANCE == null) {
42+
INSTANCE = new Schedulers();
43+
}
44+
return INSTANCE;
45+
}
3646

3747
private Schedulers() {
3848
RxJavaSchedulersHook hook = RxJavaPlugins.getInstance().getSchedulersHook();
@@ -86,7 +96,7 @@ public static Scheduler trampoline() {
8696
* @return a {@link Scheduler} that creates new threads
8797
*/
8898
public static Scheduler newThread() {
89-
return INSTANCE.newThreadScheduler;
99+
return getInstance().newThreadScheduler;
90100
}
91101

92102
/**
@@ -101,7 +111,7 @@ public static Scheduler newThread() {
101111
* @return a {@link Scheduler} meant for computation-bound work
102112
*/
103113
public static Scheduler computation() {
104-
return INSTANCE.computationScheduler;
114+
return getInstance().computationScheduler;
105115
}
106116

107117
/**
@@ -118,7 +128,7 @@ public static Scheduler computation() {
118128
* @return a {@link Scheduler} meant for IO-bound work
119129
*/
120130
public static Scheduler io() {
121-
return INSTANCE.ioScheduler;
131+
return getInstance().ioScheduler;
122132
}
123133

124134
/**
@@ -141,13 +151,27 @@ public static TestScheduler test() {
141151
public static Scheduler from(Executor executor) {
142152
return new ExecutorScheduler(executor);
143153
}
154+
155+
/**
156+
* Resets the current {@link Schedulers} instance.
157+
* <p>
158+
* This API is experimental. Resetting the schedulers is dangerous
159+
* during application runtime and also bad code could invoke it in
160+
* the middle of an application life-cycle and really break applications
161+
* if not used cautiously.
162+
*/
163+
@Experimental
164+
public static void reset() {
165+
shutdown();
166+
INSTANCE = null;
167+
}
144168

145169
/**
146170
* Starts those standard Schedulers which support the SchedulerLifecycle interface.
147171
* <p>The operation is idempotent and threadsafe.
148172
*/
149173
/* public test only */ static void start() {
150-
Schedulers s = INSTANCE;
174+
Schedulers s = getInstance();
151175
synchronized (s) {
152176
if (s.computationScheduler instanceof SchedulerLifecycle) {
153177
((SchedulerLifecycle) s.computationScheduler).start();
@@ -170,7 +194,7 @@ public static Scheduler from(Executor executor) {
170194
* <p>The operation is idempotent and threadsafe.
171195
*/
172196
public static void shutdown() {
173-
Schedulers s = INSTANCE;
197+
Schedulers s = getInstance();
174198
synchronized (s) {
175199
if (s.computationScheduler instanceof SchedulerLifecycle) {
176200
((SchedulerLifecycle) s.computationScheduler).shutdown();
@@ -189,4 +213,4 @@ public static void shutdown() {
189213
RxRingBuffer.SPMC_POOL.shutdown();
190214
}
191215
}
192-
}
216+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package rx.schedulers;
2+
3+
4+
import org.junit.Test;
5+
import rx.Scheduler;
6+
import rx.internal.schedulers.*;
7+
import rx.plugins.RxJavaPlugins;
8+
import rx.plugins.RxJavaSchedulersHook;
9+
10+
import static org.junit.Assert.assertTrue;
11+
12+
public class ResetSchedulersTest {
13+
14+
@Test
15+
public void reset() {
16+
RxJavaSchedulersHook originalHook = RxJavaPlugins.getInstance().getSchedulersHook();
17+
RxJavaPlugins.getInstance().reset();
18+
19+
final TestScheduler testScheduler = new TestScheduler();
20+
RxJavaPlugins.getInstance().registerSchedulersHook(new RxJavaSchedulersHook() {
21+
@Override
22+
public Scheduler getComputationScheduler() {
23+
return testScheduler;
24+
}
25+
26+
@Override
27+
public Scheduler getIOScheduler() {
28+
return testScheduler;
29+
}
30+
31+
@Override
32+
public Scheduler getNewThreadScheduler() {
33+
return testScheduler;
34+
}
35+
});
36+
Schedulers.reset();
37+
38+
assertTrue(Schedulers.io().equals(testScheduler));
39+
assertTrue(Schedulers.computation().equals(testScheduler));
40+
assertTrue(Schedulers.newThread().equals(testScheduler));
41+
42+
RxJavaPlugins.getInstance().reset();
43+
RxJavaPlugins.getInstance().registerSchedulersHook(originalHook);
44+
Schedulers.reset();
45+
46+
assertTrue(Schedulers.io() instanceof CachedThreadScheduler);
47+
assertTrue(Schedulers.computation() instanceof EventLoopsScheduler);
48+
assertTrue(Schedulers.newThread() instanceof rx.internal.schedulers.NewThreadScheduler);
49+
}
50+
51+
}

0 commit comments

Comments
 (0)