Skip to content

Commit 94de8ee

Browse files
committed
Merge pull request #2655 from akarnokd/Issue2654
SwitchOnNext: fix upstream producer replacing the ops own producer
2 parents bc1ed77 + 2c2051f commit 94de8ee

File tree

2 files changed

+53
-8
lines changed

2 files changed

+53
-8
lines changed

src/main/java/rx/internal/operators/OperatorSwitch.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ public static <T> OperatorSwitch<T> instance() {
4949
private OperatorSwitch() { }
5050
@Override
5151
public Subscriber<? super Observable<? extends T>> call(final Subscriber<? super T> child) {
52-
return new SwitchSubscriber<T>(child);
52+
SwitchSubscriber<T> sws = new SwitchSubscriber<T>(child);
53+
child.add(sws);
54+
return sws;
5355
}
5456

5557
private static final class SwitchSubscriber<T> extends Subscriber<Observable<? extends T>> {
@@ -75,7 +77,6 @@ private static final class SwitchSubscriber<T> extends Subscriber<Observable<? e
7577
volatile boolean infinite = false;
7678

7779
public SwitchSubscriber(Subscriber<? super T> child) {
78-
super(child);
7980
s = new SerializedSubscriber<T>(child);
8081
ssub = new SerialSubscription();
8182
child.add(ssub);

src/test/java/rx/internal/operators/OperatorSwitchTest.java

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,25 @@
1818
import static org.junit.Assert.assertTrue;
1919
import static org.mockito.Matchers.any;
2020
import static org.mockito.Matchers.anyString;
21-
import static org.mockito.Mockito.inOrder;
22-
import static org.mockito.Mockito.mock;
23-
import static org.mockito.Mockito.never;
24-
import static org.mockito.Mockito.times;
25-
import static org.mockito.Mockito.verify;
21+
import static org.mockito.Mockito.*;
2622

2723
import java.util.Arrays;
2824
import java.util.concurrent.TimeUnit;
2925
import java.util.concurrent.atomic.AtomicBoolean;
3026

27+
import org.junit.Assert;
3128
import org.junit.Before;
3229
import org.junit.Test;
3330
import org.mockito.InOrder;
3431

35-
import rx.*;
32+
import rx.Observable;
33+
import rx.Observer;
34+
import rx.Producer;
35+
import rx.Scheduler;
36+
import rx.Subscriber;
3637
import rx.exceptions.TestException;
3738
import rx.functions.Action0;
39+
import rx.functions.Func1;
3840
import rx.observers.TestSubscriber;
3941
import rx.schedulers.TestScheduler;
4042

@@ -530,4 +532,46 @@ public void call(final Subscriber<? super Observable<Integer>> subscriber) {
530532
).take(1).subscribe();
531533
assertTrue("Switch doesn't propagate 'unsubscribe'", isUnsubscribed.get());
532534
}
535+
/** The upstream producer hijacked the switch producer stopping the requests aimed at the inner observables. */
536+
@Test
537+
public void testIssue2654() {
538+
Observable<String> oneItem = Observable.just("Hello").mergeWith(Observable.<String>never());
539+
540+
Observable<String> src = oneItem.switchMap(new Func1<String, Observable<String>>() {
541+
@Override
542+
public Observable<String> call(final String s) {
543+
return Observable.just(s)
544+
.mergeWith(Observable.interval(10, TimeUnit.MILLISECONDS)
545+
.map(new Func1<Long, String>() {
546+
@Override
547+
public String call(Long i) {
548+
return s + " " + i;
549+
}
550+
})).take(250);
551+
}
552+
})
553+
.share()
554+
;
555+
556+
TestSubscriber<String> ts = new TestSubscriber<String>() {
557+
@Override
558+
public void onNext(String t) {
559+
super.onNext(t);
560+
if (getOnNextEvents().size() == 250) {
561+
onCompleted();
562+
unsubscribe();
563+
}
564+
}
565+
};
566+
src.subscribe(ts);
567+
568+
ts.awaitTerminalEvent(10, TimeUnit.SECONDS);
569+
570+
System.out.println("> testIssue2654: " + ts.getOnNextEvents().size());
571+
572+
ts.assertTerminalEvent();
573+
ts.assertNoErrors();
574+
575+
Assert.assertEquals(250, ts.getOnNextEvents().size());
576+
}
533577
}

0 commit comments

Comments
 (0)