15
15
*/
16
16
package rx .internal .reactivestreams ;
17
17
18
+ import java .util .concurrent .ConcurrentHashMap ;
19
+ import java .util .concurrent .ConcurrentMap ;
20
+ import java .util .concurrent .atomic .AtomicBoolean ;
21
+ import java .util .concurrent .atomic .AtomicLong ;
22
+
18
23
import org .reactivestreams .Publisher ;
19
24
import org .reactivestreams .Subscriber ;
20
25
import org .reactivestreams .Subscription ;
21
- import rx .Observable ;
22
26
23
- import java .util .HashSet ;
24
- import java .util .Set ;
25
- import java .util .concurrent .atomic .AtomicBoolean ;
27
+ import rx .Observable ;
28
+ import rx .internal .operators .BackpressureUtils ;
26
29
27
30
public class PublisherAdapter <T > implements Publisher <T > {
28
31
29
32
private final Observable <T > observable ;
30
33
31
- private final Set <Subscriber <?>> subscribers = new HashSet <Subscriber <?>>();
34
+ private final ConcurrentMap <Subscriber <?>, Object > subscribers = new ConcurrentHashMap <Subscriber <?>, Object >();
32
35
33
36
public PublisherAdapter (final Observable <T > observable ) {
34
37
this .observable = observable .serialize ();
35
38
}
36
39
37
40
@ Override
38
41
public void subscribe (final Subscriber <? super T > s ) {
39
- if (subscribers .add ( s ) ) {
42
+ if (subscribers .putIfAbsent ( s , s ) == null ) {
40
43
observable .subscribe (new rx .Subscriber <T >() {
41
44
private final AtomicBoolean done = new AtomicBoolean ();
42
-
45
+ private final AtomicLong childRequested = new AtomicLong ();
43
46
private void doRequest (long n ) {
44
47
if (!done .get ()) {
48
+ BackpressureUtils .getAndAddRequest (childRequested , n );
45
49
request (n );
46
50
}
47
51
}
@@ -55,6 +59,7 @@ public void request(long n) {
55
59
if (n < 1 ) {
56
60
unsubscribe ();
57
61
onError (new IllegalArgumentException ("3.9 While the Subscription is not cancelled, Subscription.request(long n) MUST throw a java.lang.IllegalArgumentException if the argument is <= 0." ));
62
+ return ;
58
63
}
59
64
60
65
requested .set (true );
@@ -98,7 +103,16 @@ public void onError(Throwable e) {
98
103
@ Override
99
104
public void onNext (T t ) {
100
105
if (!done .get ()) {
101
- s .onNext (t );
106
+ if (childRequested .get () > 0 ) {
107
+ s .onNext (t );
108
+ childRequested .decrementAndGet ();
109
+ } else {
110
+ try {
111
+ onError (new IllegalStateException ("1.1 source doesn't respect backpressure" ));
112
+ } finally {
113
+ unsubscribe ();
114
+ }
115
+ }
102
116
}
103
117
}
104
118
});
0 commit comments