Skip to content

Commit 68d7600

Browse files
Merge pull request #745 from zsxwing/issue-737
Fixed issue #737
2 parents 57376d0 + 5fe7d1d commit 68d7600

File tree

2 files changed

+72
-16
lines changed

2 files changed

+72
-16
lines changed

rxjava-core/src/main/java/rx/operators/OperationSwitch.java

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import rx.Observer;
2121
import rx.Subscription;
2222
import rx.subscriptions.CompositeSubscription;
23-
import rx.subscriptions.MultipleAssignmentSubscription;
23+
import rx.subscriptions.SerialSubscription;
2424
import rx.util.functions.Func1;
2525

2626
/**
@@ -62,8 +62,7 @@ public Subscription onSubscribe(Observer<? super T> observer) {
6262
SafeObservableSubscription parent;
6363
parent = new SafeObservableSubscription();
6464

65-
MultipleAssignmentSubscription child;
66-
child = new MultipleAssignmentSubscription();
65+
SerialSubscription child = new SerialSubscription();
6766

6867
parent.wrap(sequences.subscribe(new SwitchObserver<T>(observer, parent, child)));
6968

@@ -76,13 +75,13 @@ private static class SwitchObserver<T> implements Observer<Observable<? extends
7675
private final Object gate;
7776
private final Observer<? super T> observer;
7877
private final SafeObservableSubscription parent;
79-
private final MultipleAssignmentSubscription child;
78+
private final SerialSubscription child;
8079
private long latest;
8180
private boolean stopped;
8281
private boolean hasLatest;
8382

8483
public SwitchObserver(Observer<? super T> observer, SafeObservableSubscription parent,
85-
MultipleAssignmentSubscription child) {
84+
SerialSubscription child) {
8685
this.observer = observer;
8786
this.parent = parent;
8887
this.child = child;
@@ -97,8 +96,7 @@ public void onNext(Observable<? extends T> args) {
9796
this.hasLatest = true;
9897
}
9998

100-
final SafeObservableSubscription sub;
101-
sub = new SafeObservableSubscription();
99+
final SafeObservableSubscription sub = new SafeObservableSubscription();
102100
sub.wrap(args.subscribe(new Observer<T>() {
103101
@Override
104102
public void onNext(T args) {
@@ -111,28 +109,35 @@ public void onNext(T args) {
111109

112110
@Override
113111
public void onError(Throwable e) {
112+
sub.unsubscribe();
113+
SafeObservableSubscription s = null;
114114
synchronized (gate) {
115-
sub.unsubscribe();
116115
if (latest == id) {
117116
SwitchObserver.this.observer.onError(e);
118-
SwitchObserver.this.parent.unsubscribe();
117+
s = SwitchObserver.this.parent;
119118
}
120119
}
120+
if(s != null) {
121+
s.unsubscribe();
122+
}
121123
}
122124

123125
@Override
124126
public void onCompleted() {
127+
sub.unsubscribe();
128+
SafeObservableSubscription s = null;
125129
synchronized (gate) {
126-
sub.unsubscribe();
127130
if (latest == id) {
128131
SwitchObserver.this.hasLatest = false;
129-
}
130132

131-
if (stopped) {
132-
SwitchObserver.this.observer.onCompleted();
133-
SwitchObserver.this.parent.unsubscribe();
133+
if (stopped) {
134+
SwitchObserver.this.observer.onCompleted();
135+
s = SwitchObserver.this.parent;
136+
}
134137
}
135-
138+
}
139+
if(s != null) {
140+
s.unsubscribe();
136141
}
137142
}
138143

@@ -152,13 +157,17 @@ public void onError(Throwable e) {
152157

153158
@Override
154159
public void onCompleted() {
160+
SafeObservableSubscription s = null;
155161
synchronized (gate) {
156162
this.stopped = true;
157163
if (!this.hasLatest) {
158164
this.observer.onCompleted();
159-
this.parent.unsubscribe();
165+
s = this.parent;
160166
}
161167
}
168+
if(s != null) {
169+
s.unsubscribe();
170+
}
162171
}
163172

164173
}

rxjava-core/src/test/java/rx/operators/OperationSwitchTest.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,4 +380,51 @@ public void call() {
380380
@SuppressWarnings("serial")
381381
private class TestException extends Throwable {
382382
}
383+
384+
@Test
385+
public void testSwitchIssue737() {
386+
// https://github.com/Netflix/RxJava/issues/737
387+
Observable<Observable<String>> source = Observable.create(new Observable.OnSubscribeFunc<Observable<String>>() {
388+
@Override
389+
public Subscription onSubscribe(Observer<? super Observable<String>> observer) {
390+
publishNext(observer, 0, Observable.create(new Observable.OnSubscribeFunc<String>() {
391+
@Override
392+
public Subscription onSubscribe(Observer<? super String> observer) {
393+
publishNext(observer, 10, "1-one");
394+
publishNext(observer, 20, "1-two");
395+
// The following events will be ignored
396+
publishNext(observer, 30, "1-three");
397+
publishCompleted(observer, 40);
398+
return Subscriptions.empty();
399+
}
400+
}));
401+
publishNext(observer, 25, Observable.create(new Observable.OnSubscribeFunc<String>() {
402+
@Override
403+
public Subscription onSubscribe(Observer<? super String> observer) {
404+
publishNext(observer, 10, "2-one");
405+
publishNext(observer, 20, "2-two");
406+
publishNext(observer, 30, "2-three");
407+
publishCompleted(observer, 40);
408+
return Subscriptions.empty();
409+
}
410+
}));
411+
publishCompleted(observer, 30);
412+
return Subscriptions.empty();
413+
}
414+
});
415+
416+
Observable<String> sampled = Observable.create(OperationSwitch.switchDo(source));
417+
sampled.subscribe(observer);
418+
419+
scheduler.advanceTimeTo(1000, TimeUnit.MILLISECONDS);
420+
421+
InOrder inOrder = inOrder(observer);
422+
inOrder.verify(observer, times(1)).onNext("1-one");
423+
inOrder.verify(observer, times(1)).onNext("1-two");
424+
inOrder.verify(observer, times(1)).onNext("2-one");
425+
inOrder.verify(observer, times(1)).onNext("2-two");
426+
inOrder.verify(observer, times(1)).onNext("2-three");
427+
inOrder.verify(observer, times(1)).onCompleted();
428+
inOrder.verifyNoMoreInteractions();
429+
}
383430
}

0 commit comments

Comments
 (0)