Skip to content

Commit e6086d4

Browse files
Merge pull request #1309 from benjchristensen/subscriber-subscription
Hide ChainedSubscription/SubscriptionList from Public API
2 parents 6417f0b + 459da07 commit e6086d4

File tree

7 files changed

+69
-82
lines changed

7 files changed

+69
-82
lines changed

Diff for: rxjava-core/src/main/java/rx/Subscriber.java

+5-12
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616
package rx;
1717

18-
import rx.subscriptions.ChainedSubscription;
18+
import rx.internal.util.SubscriptionList;
1919
import rx.subscriptions.CompositeSubscription;
2020

2121
/**
@@ -32,27 +32,20 @@
3232
*/
3333
public abstract class Subscriber<T> implements Observer<T>, Subscription {
3434

35-
private final ChainedSubscription cs;
35+
private final SubscriptionList cs;
3636

37-
protected Subscriber(ChainedSubscription cs) {
38-
if (cs == null) {
39-
throw new IllegalArgumentException("The CompositeSubscription can not be null");
40-
}
41-
this.cs = cs;
42-
}
43-
4437
@Deprecated
4538
protected Subscriber(CompositeSubscription cs) {
46-
this(new ChainedSubscription());
39+
this.cs = new SubscriptionList();
4740
add(cs);
4841
}
4942

5043
protected Subscriber() {
51-
this(new ChainedSubscription());
44+
this.cs = new SubscriptionList();
5245
}
5346

5447
protected Subscriber(Subscriber<?> op) {
55-
this(op.cs);
48+
this.cs = op.cs;
5649
}
5750

5851
/**

Diff for: rxjava-core/src/main/java/rx/internal/operators/OperatorGroupBy.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import rx.functions.Action0;
2727
import rx.functions.Func1;
2828
import rx.observables.GroupedObservable;
29-
import rx.subscriptions.ChainedSubscription;
3029
import rx.subscriptions.Subscriptions;
3130

3231
/**
@@ -55,7 +54,7 @@ static final class GroupBySubscriber<K, T> extends Subscriber<T> {
5554
public GroupBySubscriber(Func1<? super T, ? extends K> keySelector, Subscriber<? super GroupedObservable<K, T>> child) {
5655
// a new CompositeSubscription to decouple the subscription as the inner subscriptions need a separate lifecycle
5756
// and will unsubscribe on this parent if they are all unsubscribed
58-
super(new ChainedSubscription());
57+
super();
5958
this.keySelector = keySelector;
6059
this.child = child;
6160
}

Diff for: rxjava-core/src/main/java/rx/internal/operators/OperatorPivot.java

+9-17
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,17 @@
2626
import rx.Observable.OnSubscribe;
2727
import rx.Observable.Operator;
2828
import rx.Subscriber;
29+
import rx.Subscription;
2930
import rx.functions.Action0;
3031
import rx.observables.GroupedObservable;
31-
import rx.subscriptions.ChainedSubscription;
3232
import rx.subscriptions.Subscriptions;
3333

3434
public final class OperatorPivot<K1, K2, T> implements Operator<GroupedObservable<K2, GroupedObservable<K1, T>>, GroupedObservable<K1, GroupedObservable<K2, T>>> {
3535

3636
@Override
3737
public Subscriber<? super GroupedObservable<K1, GroupedObservable<K2, T>>> call(final Subscriber<? super GroupedObservable<K2, GroupedObservable<K1, T>>> child) {
3838
final AtomicReference<State> state = new AtomicReference<State>(State.create());
39-
final PivotSubscriber<K1, K2, T> pivotSubscriber = new PivotSubscriber<K1, K2, T>(new ChainedSubscription(), child, state);
39+
final PivotSubscriber<K1, K2, T> pivotSubscriber = new PivotSubscriber<K1, K2, T>(child, state);
4040
child.add(Subscriptions.create(new Action0() {
4141

4242
@Override
@@ -61,21 +61,14 @@ public void call() {
6161
}
6262

6363
private static final class PivotSubscriber<K1, K2, T> extends Subscriber<GroupedObservable<K1, GroupedObservable<K2, T>>> {
64-
/*
65-
* needs to decouple the subscription as the inner subscriptions need a separate lifecycle
66-
* and will unsubscribe on this parent if they are all unsubscribed
67-
*/
68-
private final ChainedSubscription parentSubscription;
6964
private final Subscriber<? super GroupedObservable<K2, GroupedObservable<K1, T>>> child;
7065
private final AtomicReference<State> state;
7166
private final GroupState<K1, K2, T> groups;
7267

73-
private PivotSubscriber(ChainedSubscription parentSubscription, Subscriber<? super GroupedObservable<K2, GroupedObservable<K1, T>>> child, AtomicReference<State> state) {
74-
super(parentSubscription);
75-
this.parentSubscription = parentSubscription;
68+
private PivotSubscriber(Subscriber<? super GroupedObservable<K2, GroupedObservable<K1, T>>> child, AtomicReference<State> state) {
7669
this.child = child;
7770
this.state = state;
78-
this.groups = new GroupState<K1, K2, T>(parentSubscription, child);
71+
this.groups = new GroupState<K1, K2, T>(this, child);
7972
}
8073

8174
@Override
@@ -102,7 +95,7 @@ public void onError(Throwable e) {
10295
@Override
10396
public void onNext(final GroupedObservable<K1, GroupedObservable<K2, T>> k1Group) {
10497
groups.startK1Group(state, k1Group.getKey());
105-
k1Group.unsafeSubscribe(new Subscriber<GroupedObservable<K2, T>>(parentSubscription) {
98+
k1Group.unsafeSubscribe(new Subscriber<GroupedObservable<K2, T>>(this) {
10699

107100
@Override
108101
public void onCompleted() {
@@ -124,7 +117,7 @@ public void onNext(final GroupedObservable<K2, T> k2Group) {
124117
// we have been unsubscribed
125118
return;
126119
}
127-
k2Group.unsafeSubscribe(new Subscriber<T>(parentSubscription) {
120+
k2Group.unsafeSubscribe(new Subscriber<T>(this) {
128121

129122
@Override
130123
public void onCompleted() {
@@ -158,16 +151,15 @@ public void onNext(T t) {
158151
private static final class GroupState<K1, K2, T> {
159152
private final ConcurrentHashMap<KeyPair<K1, K2>, Inner<K1, K2, T>> innerSubjects = new ConcurrentHashMap<KeyPair<K1, K2>, Inner<K1, K2, T>>();
160153
private final ConcurrentHashMap<K2, Outer<K1, K2, T>> outerSubjects = new ConcurrentHashMap<K2, Outer<K1, K2, T>>();
161-
private final ChainedSubscription parentSubscription;
154+
private final Subscription parentSubscription;
162155
private final Subscriber<? super GroupedObservable<K2, GroupedObservable<K1, T>>> child;
163156
/** Indicates a terminal state. */
164157
volatile int completed;
165158
/** Field updater for completed. */
166159
@SuppressWarnings("rawtypes")
167-
static final AtomicIntegerFieldUpdater<GroupState> COMPLETED_UPDATER
168-
= AtomicIntegerFieldUpdater.newUpdater(GroupState.class, "completed");
160+
static final AtomicIntegerFieldUpdater<GroupState> COMPLETED_UPDATER = AtomicIntegerFieldUpdater.newUpdater(GroupState.class, "completed");
169161

170-
public GroupState(ChainedSubscription parentSubscription, Subscriber<? super GroupedObservable<K2, GroupedObservable<K1, T>>> child) {
162+
public GroupState(Subscription parentSubscription, Subscriber<? super GroupedObservable<K2, GroupedObservable<K1, T>>> child) {
171163
this.parentSubscription = parentSubscription;
172164
this.child = child;
173165
}

Diff for: rxjava-core/src/main/java/rx/internal/operators/OperatorTake.java

+17-17
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
import rx.Observable.Operator;
1919
import rx.Subscriber;
20-
import rx.subscriptions.ChainedSubscription;
2120

2221
/**
2322
* Returns an Observable that emits the first <code>num</code> items emitted by the source
@@ -40,22 +39,7 @@ public OperatorTake(int limit) {
4039

4140
@Override
4241
public Subscriber<? super T> call(final Subscriber<? super T> child) {
43-
final ChainedSubscription parent = new ChainedSubscription();
44-
if (limit == 0) {
45-
child.onCompleted();
46-
parent.unsubscribe();
47-
}
48-
49-
/*
50-
* We decouple the parent and child subscription so there can be multiple take() in a chain
51-
* such as for the groupBy Observer use case where you may take(1) on groups and take(20) on the children.
52-
*
53-
* Thus, we only unsubscribe UPWARDS to the parent and an onComplete DOWNSTREAM.
54-
*
55-
* However, if we receive an unsubscribe from the child we still want to propagate it upwards so we register 'parent' with 'child'
56-
*/
57-
child.add(parent);
58-
return new Subscriber<T>(parent) {
42+
Subscriber<T> parent = new Subscriber<T>() {
5943

6044
int count = 0;
6145
boolean completed = false;
@@ -87,6 +71,22 @@ public void onNext(T i) {
8771
}
8872

8973
};
74+
75+
if (limit == 0) {
76+
child.onCompleted();
77+
parent.unsubscribe();
78+
}
79+
80+
/*
81+
* We decouple the parent and child subscription so there can be multiple take() in a chain
82+
* such as for the groupBy Observer use case where you may take(1) on groups and take(20) on the children.
83+
*
84+
* Thus, we only unsubscribe UPWARDS to the parent and an onComplete DOWNSTREAM.
85+
*
86+
* However, if we receive an unsubscribe from the child we still want to propagate it upwards so we register 'parent' with 'child'
87+
*/
88+
child.add(parent);
89+
return parent;
9090
}
9191

9292
}

Diff for: rxjava-core/src/main/java/rx/internal/operators/OperatorUnsubscribeOn.java

+22-20
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import rx.Scheduler;
2020
import rx.Subscriber;
2121
import rx.functions.Action0;
22-
import rx.subscriptions.ChainedSubscription;
2322
import rx.subscriptions.Subscriptions;
2423

2524
/**
@@ -36,25 +35,7 @@ public OperatorUnsubscribeOn(Scheduler scheduler) {
3635

3736
@Override
3837
public Subscriber<? super T> call(final Subscriber<? super T> subscriber) {
39-
final ChainedSubscription parentSubscription = new ChainedSubscription();
40-
subscriber.add(Subscriptions.create(new Action0() {
41-
42-
@Override
43-
public void call() {
44-
final Scheduler.Worker inner = scheduler.createWorker();
45-
inner.schedule(new Action0() {
46-
47-
@Override
48-
public void call() {
49-
parentSubscription.unsubscribe();
50-
inner.unsubscribe();
51-
}
52-
});
53-
}
54-
55-
}));
56-
57-
return new Subscriber<T>(parentSubscription) {
38+
final Subscriber<T> parent = new Subscriber<T>() {
5839

5940
@Override
6041
public void onCompleted() {
@@ -72,5 +53,26 @@ public void onNext(T t) {
7253
}
7354

7455
};
56+
57+
subscriber.add(Subscriptions.create(new Action0() {
58+
59+
@Override
60+
public void call() {
61+
final Scheduler.Worker inner = scheduler.createWorker();
62+
inner.schedule(new Action0() {
63+
64+
@Override
65+
public void call() {
66+
parent.unsubscribe();
67+
inner.unsubscribe();
68+
}
69+
});
70+
}
71+
72+
}));
73+
74+
return parent;
75+
76+
7577
}
7678
}

Diff for: rxjava-core/src/main/java/rx/subscriptions/ChainedSubscription.java renamed to rxjava-core/src/main/java/rx/internal/util/SubscriptionList.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package rx.subscriptions;
16+
package rx.internal.util;
1717

1818
import java.util.ArrayList;
1919
import java.util.Arrays;
@@ -29,15 +29,15 @@
2929
*
3030
* @see <a href="http://msdn.microsoft.com/en-us/library/system.reactive.disposables.compositedisposable(v=vs.103).aspx">Rx.Net equivalent CompositeDisposable</a>
3131
*/
32-
public final class ChainedSubscription implements Subscription {
32+
public final class SubscriptionList implements Subscription {
3333

3434
private List<Subscription> subscriptions;
3535
private boolean unsubscribed = false;
3636

37-
public ChainedSubscription() {
37+
public SubscriptionList() {
3838
}
3939

40-
public ChainedSubscription(final Subscription... subscriptions) {
40+
public SubscriptionList(final Subscription... subscriptions) {
4141
this.subscriptions = new LinkedList<Subscription>(Arrays.asList(subscriptions));
4242
}
4343

@@ -47,8 +47,8 @@ public synchronized boolean isUnsubscribed() {
4747
}
4848

4949
/**
50-
* Adds a new {@link Subscription} to this {@code ChainedSubscription} if the {@code ChainedSubscription} is
51-
* not yet unsubscribed. If the {@code ChainedSubscription} <em>is</em> unsubscribed, {@code add} will
50+
* Adds a new {@link Subscription} to this {@code SubscriptionList} if the {@code SubscriptionList} is
51+
* not yet unsubscribed. If the {@code SubscriptionList} <em>is</em> unsubscribed, {@code add} will
5252
* indicate this by explicitly unsubscribing the new {@code Subscription} as well.
5353
*
5454
* @param s

Diff for: rxjava-core/src/test/java/rx/subscriptions/ChainedSubscriptionTest.java renamed to rxjava-core/src/test/java/rx/internal/util/SubscriptionListTest.java

+9-8
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package rx.subscriptions;
16+
package rx.internal.util;
1717

1818
import static org.junit.Assert.assertEquals;
1919
import static org.junit.Assert.assertFalse;
@@ -29,13 +29,14 @@
2929

3030
import rx.Subscription;
3131
import rx.exceptions.CompositeException;
32+
import rx.internal.util.SubscriptionList;
3233

33-
public class ChainedSubscriptionTest {
34+
public class SubscriptionListTest {
3435

3536
@Test
3637
public void testSuccess() {
3738
final AtomicInteger counter = new AtomicInteger();
38-
ChainedSubscription s = new ChainedSubscription();
39+
SubscriptionList s = new SubscriptionList();
3940
s.add(new Subscription() {
4041

4142
@Override
@@ -70,7 +71,7 @@ public boolean isUnsubscribed() {
7071
@Test(timeout = 1000)
7172
public void shouldUnsubscribeAll() throws InterruptedException {
7273
final AtomicInteger counter = new AtomicInteger();
73-
final ChainedSubscription s = new ChainedSubscription();
74+
final SubscriptionList s = new SubscriptionList();
7475

7576
final int count = 10;
7677
final CountDownLatch start = new CountDownLatch(1);
@@ -117,7 +118,7 @@ public void run() {
117118
@Test
118119
public void testException() {
119120
final AtomicInteger counter = new AtomicInteger();
120-
ChainedSubscription s = new ChainedSubscription();
121+
SubscriptionList s = new SubscriptionList();
121122
s.add(new Subscription() {
122123

123124
@Override
@@ -159,7 +160,7 @@ public boolean isUnsubscribed() {
159160
@Test
160161
public void testCompositeException() {
161162
final AtomicInteger counter = new AtomicInteger();
162-
ChainedSubscription s = new ChainedSubscription();
163+
SubscriptionList s = new SubscriptionList();
163164
s.add(new Subscription() {
164165

165166
@Override
@@ -215,7 +216,7 @@ public boolean isUnsubscribed() {
215216
@Test
216217
public void testUnsubscribeIdempotence() {
217218
final AtomicInteger counter = new AtomicInteger();
218-
ChainedSubscription s = new ChainedSubscription();
219+
SubscriptionList s = new SubscriptionList();
219220
s.add(new Subscription() {
220221

221222
@Override
@@ -241,7 +242,7 @@ public boolean isUnsubscribed() {
241242
public void testUnsubscribeIdempotenceConcurrently()
242243
throws InterruptedException {
243244
final AtomicInteger counter = new AtomicInteger();
244-
final ChainedSubscription s = new ChainedSubscription();
245+
final SubscriptionList s = new SubscriptionList();
245246

246247
final int count = 10;
247248
final CountDownLatch start = new CountDownLatch(1);

0 commit comments

Comments
 (0)