32
32
*/
33
33
34
34
import java .util .concurrent .atomic .AtomicInteger ;
35
- import java .util .concurrent .atomic .AtomicReference ;
36
35
37
36
import rx .Observable ;
38
37
import rx .Observable .Operator ;
39
- import rx .Scheduler ;
40
38
import rx .Scheduler .Inner ;
41
39
import rx .Subscriber ;
42
- import rx .Subscription ;
43
40
import rx .functions .Action1 ;
44
41
import rx .schedulers .Schedulers ;
42
+ import rx .subscriptions .SerialSubscription ;
45
43
46
44
public class OperatorRetry <T > implements Operator <T , Observable <T >> {
47
45
@@ -58,63 +56,59 @@ public OperatorRetry() {
58
56
}
59
57
60
58
@ Override
61
- public Subscriber <? super Observable <T >> call (final Subscriber <? super T > s ) {
62
- return new Subscriber <Observable <T >>(s ) {
59
+ public Subscriber <? super Observable <T >> call (final Subscriber <? super T > child ) {
60
+ final SerialSubscription serialSubscription = new SerialSubscription ();
61
+ // add serialSubscription so it gets unsubscribed if child is unsubscribed
62
+ child .add (serialSubscription );
63
+ return new Subscriber <Observable <T >>(child ) {
63
64
final AtomicInteger attempts = new AtomicInteger (0 );
64
-
65
+
65
66
@ Override
66
67
public void onCompleted () {
67
68
// ignore as we expect a single nested Observable<T>
68
69
}
69
70
70
71
@ Override
71
72
public void onError (Throwable e ) {
72
- s .onError (e );
73
+ child .onError (e );
73
74
}
74
75
75
76
@ Override
76
77
public void onNext (final Observable <T > o ) {
77
-
78
- final AtomicReference <Subscription > retrySub =new AtomicReference <Subscription >();
79
-
80
78
Schedulers .trampoline ().schedule (new Action1 <Inner >() {
81
79
82
80
@ Override
83
81
public void call (final Inner inner ) {
84
82
final Action1 <Inner > _self = this ;
85
83
attempts .incrementAndGet ();
86
- retrySub .set (o .unsafeSubscribe (new Subscriber <T >(s ) {
84
+
85
+ Subscriber <T > subscriber = new Subscriber <T >(child ) {
87
86
88
87
@ Override
89
88
public void onCompleted () {
90
- s .onCompleted ();
89
+ child .onCompleted ();
91
90
}
92
91
93
92
@ Override
94
93
public void onError (Throwable e ) {
95
94
if ((retryCount == INFINITE_RETRY || attempts .get () <= retryCount ) && !inner .isUnsubscribed ()) {
96
95
// retry again
97
- inner .schedule (new Action1 <Inner >() {
98
- @ Override
99
- public void call (Inner inner )
100
- {
101
- // Remove the failed subscription first
102
- retrySub .get ().unsubscribe ();
103
- _self .call (inner );
104
- }
105
- });
96
+ inner .schedule (_self );
106
97
} else {
107
98
// give up and pass the failure
108
- s .onError (e );
99
+ child .onError (e );
109
100
}
110
101
}
111
102
112
103
@ Override
113
104
public void onNext (T v ) {
114
- s .onNext (v );
105
+ child .onNext (v );
115
106
}
116
107
117
- }));
108
+ };
109
+ // register this Subscription (and unsubscribe previous if exists)
110
+ serialSubscription .set (subscriber );
111
+ o .unsafeSubscribe (subscriber );
118
112
}
119
113
});
120
114
}
0 commit comments