Skip to content

Commit 7c69cb3

Browse files
committed
make it configurable via property
1 parent e0929ee commit 7c69cb3

8 files changed

+177
-119
lines changed

src/main/java/rx/internal/schedulers/ExecutorScheduler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public Worker createWorker() {
4646

4747
/** Worker that schedules tasks on the executor indirectly through a trampoline mechanism. */
4848
static final class ExecutorSchedulerWorker extends Scheduler.Worker implements Runnable {
49-
private final Throwable creationContext = new SchedulerContextException();
49+
private final Throwable creationContext = SchedulerContextException.create();
5050
final Executor executor;
5151
// TODO: use a better performing structure for task tracking
5252
final CompositeSubscription tasks;

src/main/java/rx/internal/schedulers/NewThreadWorker.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
* @warn class description missing
3434
*/
3535
public class NewThreadWorker extends Scheduler.Worker implements Subscription {
36-
private final Throwable creationContext = new SchedulerContextException();
36+
private final Throwable creationContext = SchedulerContextException.create();
3737
private final ScheduledExecutorService executor;
3838
private final RxJavaSchedulersHook schedulersHook;
3939
volatile boolean isUnsubscribed;

src/main/java/rx/internal/schedulers/SchedulerContextException.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,26 @@
1919
* Used only for providing context around where work was scheduled should an error occur in a different thread.
2020
*/
2121
public class SchedulerContextException extends Exception {
22-
public SchedulerContextException() {
23-
super("Asynchronous work scheduled at");
22+
/**
23+
* Constant to use when disabled
24+
*/
25+
private static final Throwable CONTEXT_MISSING = new SchedulerContextException("Missing context. Enable by setting the system property \"rxjava.captureSchedulerContext=true\"");
26+
27+
static {
28+
CONTEXT_MISSING.setStackTrace(new StackTraceElement[0]);
29+
}
30+
31+
/**
32+
* @return a {@link Throwable} that captures the stack trace or a {@link Throwable} that documents how to enable the feature if needed.
33+
*/
34+
public static Throwable create() {
35+
String def = "false";
36+
String setTo = System.getProperty("rxjava.captureSchedulerContext", def);
37+
return setTo != def && "true".equals(setTo) ? new SchedulerContextException("Asynchronous work scheduled at") : CONTEXT_MISSING;
38+
}
39+
40+
private SchedulerContextException(String message) {
41+
super(message);
2442
}
2543

2644
private static final long serialVersionUID = 1L;

src/test/java/rx/schedulers/ComputationSchedulerTests.java

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import rx.functions.Action0;
3232
import rx.functions.Action1;
3333
import rx.functions.Func1;
34+
import rx.internal.schedulers.SchedulerContextException;
3435
import rx.plugins.RxJavaErrorHandler;
3536
import rx.plugins.RxJavaPlugins;
3637

@@ -176,43 +177,50 @@ public void testCancelledTaskRetention() throws InterruptedException {
176177
public void testStackTraceAcrossThreads() throws Throwable {
177178
final AtomicReference<Throwable> exceptionRef = new AtomicReference<Throwable>();
178179
final CountDownLatch done = new CountDownLatch(1);
179-
180-
RxJavaPlugins.getInstance().reset();
181-
RxJavaPlugins.getInstance().registerErrorHandler(new RxJavaErrorHandler() {
182-
@Override
183-
public void handleError(Throwable e) {
184-
exceptionRef.set(e);
185-
done.countDown();
186-
}
187-
});
180+
System.setProperty("rxjava.captureSchedulerContext", "true");
188181

189182
try {
190-
getScheduler().createWorker().schedule(new Action0() {
183+
184+
RxJavaPlugins.getInstance().reset();
185+
RxJavaPlugins.getInstance().registerErrorHandler(new RxJavaErrorHandler() {
191186
@Override
192-
public void call() {
193-
throw new RuntimeException();
187+
public void handleError(Throwable e) {
188+
exceptionRef.set(e);
189+
done.countDown();
194190
}
195191
});
196-
} catch (Exception e) {
197-
exceptionRef.set(e);
198-
done.countDown();
199-
}
200192

201-
done.await();
193+
try {
194+
getScheduler().createWorker().schedule(new Action0() {
195+
@Override
196+
public void call() {
197+
throw new RuntimeException();
198+
}
199+
});
200+
} catch (Exception e) {
201+
exceptionRef.set(e);
202+
done.countDown();
203+
}
204+
205+
done.await();
206+
207+
Throwable exception = exceptionRef.get();
208+
Throwable e = exception;
209+
while (!(e instanceof SchedulerContextException)) {
210+
e = e.getCause();
211+
}
202212

203-
Throwable exception = exceptionRef.get();
204-
Throwable e = exception;
205-
while (e != null) {
206213
StackTraceElement[] st = e.getStackTrace();
207214
for (StackTraceElement stackTraceElement : st) {
208215
if (stackTraceElement.getClassName().contains(getClass().getName())) {
209216
// pass we found this class in the stack trace.
210217
return;
211218
}
212219
}
213-
e = e.getCause();
214-
}
215220

216-
throw exception;
221+
throw exception;
222+
} finally {
223+
System.setProperty("rxjava.captureSchedulerContext", "false");
224+
}
217225
}
218226
}

src/test/java/rx/schedulers/ImmediateSchedulerTest.java

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import rx.functions.Action0;
2828
import rx.functions.Action1;
2929
import rx.functions.Func1;
30+
import rx.internal.schedulers.SchedulerContextException;
3031
import rx.plugins.RxJavaErrorHandler;
3132
import rx.plugins.RxJavaPlugins;
3233

@@ -112,43 +113,50 @@ public void call(String t) {
112113
public void testStackTraceAcrossThreads() throws Throwable {
113114
final AtomicReference<Throwable> exceptionRef = new AtomicReference<Throwable>();
114115
final CountDownLatch done = new CountDownLatch(1);
115-
116-
RxJavaPlugins.getInstance().reset();
117-
RxJavaPlugins.getInstance().registerErrorHandler(new RxJavaErrorHandler() {
118-
@Override
119-
public void handleError(Throwable e) {
120-
exceptionRef.set(e);
121-
done.countDown();
122-
}
123-
});
116+
System.setProperty("rxjava.captureSchedulerContext", "true");
124117

125118
try {
126-
getScheduler().createWorker().schedule(new Action0() {
119+
120+
RxJavaPlugins.getInstance().reset();
121+
RxJavaPlugins.getInstance().registerErrorHandler(new RxJavaErrorHandler() {
127122
@Override
128-
public void call() {
129-
throw new RuntimeException();
123+
public void handleError(Throwable e) {
124+
exceptionRef.set(e);
125+
done.countDown();
130126
}
131127
});
132-
} catch (Exception e) {
133-
exceptionRef.set(e);
134-
done.countDown();
135-
}
136128

137-
done.await();
129+
try {
130+
getScheduler().createWorker().schedule(new Action0() {
131+
@Override
132+
public void call() {
133+
throw new RuntimeException();
134+
}
135+
});
136+
} catch (Exception e) {
137+
exceptionRef.set(e);
138+
done.countDown();
139+
}
140+
141+
done.await();
142+
143+
Throwable exception = exceptionRef.get();
144+
Throwable e = exception;
145+
while (!(e instanceof SchedulerContextException)) {
146+
e = e.getCause();
147+
}
138148

139-
Throwable exception = exceptionRef.get();
140-
Throwable e = exception;
141-
while (e != null) {
142149
StackTraceElement[] st = e.getStackTrace();
143150
for (StackTraceElement stackTraceElement : st) {
144151
if (stackTraceElement.getClassName().contains(getClass().getName())) {
145152
// pass we found this class in the stack trace.
146153
return;
147154
}
148155
}
149-
e = e.getCause();
150-
}
151156

152-
throw exception;
157+
throw exception;
158+
} finally {
159+
System.setProperty("rxjava.captureSchedulerContext", "false");
160+
}
153161
}
154162
}

src/test/java/rx/schedulers/IoSchedulerTest.java

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import rx.*;
2727
import rx.Scheduler.Worker;
2828
import rx.functions.*;
29+
import rx.internal.schedulers.SchedulerContextException;
2930
import rx.plugins.RxJavaErrorHandler;
3031
import rx.plugins.RxJavaPlugins;
3132

@@ -92,43 +93,50 @@ public void testCancelledTaskRetention() throws InterruptedException {
9293
public void testStackTraceAcrossThreads() throws Throwable {
9394
final AtomicReference<Throwable> exceptionRef = new AtomicReference<Throwable>();
9495
final CountDownLatch done = new CountDownLatch(1);
95-
96-
RxJavaPlugins.getInstance().reset();
97-
RxJavaPlugins.getInstance().registerErrorHandler(new RxJavaErrorHandler() {
98-
@Override
99-
public void handleError(Throwable e) {
100-
exceptionRef.set(e);
101-
done.countDown();
102-
}
103-
});
96+
System.setProperty("rxjava.captureSchedulerContext", "true");
10497

10598
try {
106-
getScheduler().createWorker().schedule(new Action0() {
99+
100+
RxJavaPlugins.getInstance().reset();
101+
RxJavaPlugins.getInstance().registerErrorHandler(new RxJavaErrorHandler() {
107102
@Override
108-
public void call() {
109-
throw new RuntimeException();
103+
public void handleError(Throwable e) {
104+
exceptionRef.set(e);
105+
done.countDown();
110106
}
111107
});
112-
} catch (Exception e) {
113-
exceptionRef.set(e);
114-
done.countDown();
115-
}
116108

117-
done.await();
109+
try {
110+
getScheduler().createWorker().schedule(new Action0() {
111+
@Override
112+
public void call() {
113+
throw new RuntimeException();
114+
}
115+
});
116+
} catch (Exception e) {
117+
exceptionRef.set(e);
118+
done.countDown();
119+
}
120+
121+
done.await();
122+
123+
Throwable exception = exceptionRef.get();
124+
Throwable e = exception;
125+
while (!(e instanceof SchedulerContextException)) {
126+
e = e.getCause();
127+
}
118128

119-
Throwable exception = exceptionRef.get();
120-
Throwable e = exception;
121-
while (e != null) {
122129
StackTraceElement[] st = e.getStackTrace();
123130
for (StackTraceElement stackTraceElement : st) {
124131
if (stackTraceElement.getClassName().contains(getClass().getName())) {
125132
// pass we found this class in the stack trace.
126133
return;
127134
}
128135
}
129-
e = e.getCause();
130-
}
131136

132-
throw exception;
137+
throw exception;
138+
} finally {
139+
System.setProperty("rxjava.captureSchedulerContext", "false");
140+
}
133141
}
134142
}

src/test/java/rx/schedulers/NewThreadSchedulerTest.java

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import rx.Scheduler;
2828
import rx.functions.Action0;
2929
import rx.internal.schedulers.ScheduledAction;
30+
import rx.internal.schedulers.SchedulerContextException;
3031
import rx.plugins.RxJavaErrorHandler;
3132
import rx.plugins.RxJavaPlugins;
3233
import rx.subscriptions.Subscriptions;
@@ -90,43 +91,50 @@ public void call() {
9091
public void testStackTraceAcrossThreads() throws Throwable {
9192
final AtomicReference<Throwable> exceptionRef = new AtomicReference<Throwable>();
9293
final CountDownLatch done = new CountDownLatch(1);
93-
94-
RxJavaPlugins.getInstance().reset();
95-
RxJavaPlugins.getInstance().registerErrorHandler(new RxJavaErrorHandler() {
96-
@Override
97-
public void handleError(Throwable e) {
98-
exceptionRef.set(e);
99-
done.countDown();
100-
}
101-
});
94+
System.setProperty("rxjava.captureSchedulerContext", "true");
10295

10396
try {
104-
getScheduler().createWorker().schedule(new Action0() {
97+
98+
RxJavaPlugins.getInstance().reset();
99+
RxJavaPlugins.getInstance().registerErrorHandler(new RxJavaErrorHandler() {
105100
@Override
106-
public void call() {
107-
throw new RuntimeException();
101+
public void handleError(Throwable e) {
102+
exceptionRef.set(e);
103+
done.countDown();
108104
}
109105
});
110-
} catch (Exception e) {
111-
exceptionRef.set(e);
112-
done.countDown();
113-
}
114106

115-
done.await();
107+
try {
108+
getScheduler().createWorker().schedule(new Action0() {
109+
@Override
110+
public void call() {
111+
throw new RuntimeException();
112+
}
113+
});
114+
} catch (Exception e) {
115+
exceptionRef.set(e);
116+
done.countDown();
117+
}
118+
119+
done.await();
120+
121+
Throwable exception = exceptionRef.get();
122+
Throwable e = exception;
123+
while (!(e instanceof SchedulerContextException)) {
124+
e = e.getCause();
125+
}
116126

117-
Throwable exception = exceptionRef.get();
118-
Throwable e = exception;
119-
while (e != null) {
120127
StackTraceElement[] st = e.getStackTrace();
121128
for (StackTraceElement stackTraceElement : st) {
122129
if (stackTraceElement.getClassName().contains(getClass().getName())) {
123130
// pass we found this class in the stack trace.
124131
return;
125132
}
126133
}
127-
e = e.getCause();
128-
}
129134

130-
throw exception;
135+
throw exception;
136+
} finally {
137+
System.setProperty("rxjava.captureSchedulerContext", "false");
138+
}
131139
}
132140
}

0 commit comments

Comments
 (0)