19
19
import java .util .Iterator ;
20
20
import java .util .LinkedList ;
21
21
import java .util .List ;
22
+
22
23
import rx .Observable ;
23
24
import rx .Observable .Operator ;
25
+ import rx .Subscription ;
26
+ import rx .functions .Action0 ;
27
+ import rx .subscriptions .Subscriptions ;
24
28
import rx .Observer ;
25
29
import rx .Subscriber ;
26
30
@@ -56,11 +60,29 @@ public Subscriber<? super T> call(Subscriber<? super Observable<T>> child) {
56
60
final class ExactSubscriber extends Subscriber <T > {
57
61
final Subscriber <? super Observable <T >> child ;
58
62
int count ;
59
- Observer <T > consumer ;
60
- Observable < T > producer ;
63
+ BufferUntilSubscriber <T > window ;
64
+ Subscription parentSubscription = this ;
61
65
public ExactSubscriber (Subscriber <? super Observable <T >> child ) {
62
- super (child );
66
+ /**
67
+ * See https://github.com/ReactiveX/RxJava/issues/1546
68
+ * We cannot compose through a Subscription because unsubscribing
69
+ * applies to the outer, not the inner.
70
+ */
63
71
this .child = child ;
72
+ /*
73
+ * Add unsubscribe hook to child to get unsubscribe on outer (unsubscribing on next window, not on the inner window itself)
74
+ */
75
+ child .add (Subscriptions .create (new Action0 () {
76
+
77
+ @ Override
78
+ public void call () {
79
+ // if no window we unsubscribe up otherwise wait until window ends
80
+ if (window == null ) {
81
+ parentSubscription .unsubscribe ();
82
+ }
83
+ }
84
+
85
+ }));
64
86
}
65
87
66
88
@ Override
@@ -71,36 +93,36 @@ public void onStart() {
71
93
72
94
@ Override
73
95
public void onNext (T t ) {
74
- if (count ++ % size == 0 ) {
75
- if (consumer != null ) {
76
- consumer .onCompleted ();
96
+ if (window == null ) {
97
+ window = BufferUntilSubscriber .create ();
98
+ child .onNext (window );
99
+ }
100
+ window .onNext (t );
101
+ if (++count % size == 0 ) {
102
+ window .onCompleted ();
103
+ window = null ;
104
+ if (child .isUnsubscribed ()) {
105
+ parentSubscription .unsubscribe ();
106
+ return ;
77
107
}
78
- createNewWindow ();
79
- child .onNext (producer );
80
108
}
81
- consumer .onNext (t );
82
109
}
83
110
84
111
@ Override
85
112
public void onError (Throwable e ) {
86
- if (consumer != null ) {
87
- consumer .onError (e );
113
+ if (window != null ) {
114
+ window .onError (e );
88
115
}
89
116
child .onError (e );
90
117
}
91
118
92
119
@ Override
93
120
public void onCompleted () {
94
- if (consumer != null ) {
95
- consumer .onCompleted ();
121
+ if (window != null ) {
122
+ window .onCompleted ();
96
123
}
97
124
child .onCompleted ();
98
125
}
99
- void createNewWindow () {
100
- final BufferUntilSubscriber <T > bus = BufferUntilSubscriber .create ();
101
- consumer = bus ;
102
- producer = bus ;
103
- }
104
126
}
105
127
/** Subscriber with inexact, possibly overlapping or skipping windows. */
106
128
final class InexactSubscriber extends Subscriber <T > {
0 commit comments