14
14
15
15
import com .typesafe .netty .HandlerPublisher ;
16
16
import io .netty .channel .Channel ;
17
+ import io .netty .channel .ChannelHandlerContext ;
17
18
import io .netty .util .concurrent .EventExecutor ;
19
+ import java .util .concurrent .atomic .AtomicBoolean ;
20
+ import java .util .concurrent .atomic .AtomicLong ;
18
21
import org .asynchttpclient .HttpResponseBodyPart ;
19
22
import org .asynchttpclient .netty .NettyResponseFuture ;
20
23
import org .asynchttpclient .netty .channel .ChannelManager ;
24
+ import org .reactivestreams .Subscriber ;
25
+ import org .reactivestreams .Subscription ;
21
26
import org .slf4j .Logger ;
22
27
import org .slf4j .LoggerFactory ;
23
28
@@ -28,6 +33,8 @@ public class StreamedResponsePublisher extends HandlerPublisher<HttpResponseBody
28
33
private final ChannelManager channelManager ;
29
34
private final NettyResponseFuture <?> future ;
30
35
private final Channel channel ;
36
+ private final AtomicBoolean hasOutstandingRequest = new AtomicBoolean (false );
37
+ private Throwable error ;
31
38
32
39
StreamedResponsePublisher (EventExecutor executor , ChannelManager channelManager , NettyResponseFuture <?> future , Channel channel ) {
33
40
super (executor , HttpResponseBodyPart .class );
@@ -51,7 +58,66 @@ protected void cancelled() {
51
58
channelManager .closeChannel (channel );
52
59
}
53
60
61
+ @ Override
62
+ protected void requestDemand () {
63
+ hasOutstandingRequest .set (true );
64
+ super .requestDemand ();
65
+ }
66
+
67
+ @ Override
68
+ public void channelReadComplete (ChannelHandlerContext ctx ) throws Exception {
69
+ hasOutstandingRequest .set (false );
70
+ super .channelReadComplete (ctx );
71
+ }
72
+
73
+ @ Override
74
+ public void subscribe (Subscriber <? super HttpResponseBodyPart > subscriber ) {
75
+ super .subscribe (new ErrorReplacingSubscriber (subscriber ));
76
+ }
77
+
78
+ public boolean hasOutstandingRequest () {
79
+ return hasOutstandingRequest .get ();
80
+ }
81
+
54
82
NettyResponseFuture <?> future () {
55
83
return future ;
56
84
}
85
+
86
+ public void setError (Throwable t ) {
87
+ this .error = t ;
88
+ }
89
+
90
+ private class ErrorReplacingSubscriber implements Subscriber <HttpResponseBodyPart > {
91
+
92
+ Subscriber <? super HttpResponseBodyPart > subscriber ;
93
+
94
+ ErrorReplacingSubscriber (Subscriber <? super HttpResponseBodyPart > subscriber ) {
95
+ this .subscriber = subscriber ;
96
+ }
97
+
98
+ @ Override
99
+ public void onSubscribe (Subscription s ) {
100
+ subscriber .onSubscribe (s );
101
+ }
102
+
103
+ @ Override
104
+ public void onNext (HttpResponseBodyPart httpResponseBodyPart ) {
105
+ subscriber .onNext (httpResponseBodyPart );
106
+ }
107
+
108
+ @ Override
109
+ public void onError (Throwable t ) {
110
+ subscriber .onError (t );
111
+ }
112
+
113
+ @ Override
114
+ public void onComplete () {
115
+ Throwable replacementError = error ;
116
+ if (replacementError == null ) {
117
+ subscriber .onComplete ();
118
+ } else {
119
+ subscriber .onError (replacementError );
120
+ }
121
+ }
122
+ }
57
123
}
0 commit comments