20
20
import io .reactivesocket .exceptions .CancelException ;
21
21
import io .reactivesocket .exceptions .Exceptions ;
22
22
import io .reactivesocket .internal .KnownErrorFilter ;
23
+ import io .reactivesocket .internal .RemoteReceiver ;
24
+ import io .reactivesocket .internal .RemoteSender ;
23
25
import io .reactivesocket .lease .Lease ;
24
26
import io .reactivesocket .lease .LeaseImpl ;
25
27
import io .reactivesocket .reactivestreams .extensions .DefaultSubscriber ;
26
28
import io .reactivesocket .reactivestreams .extensions .Px ;
29
+ import io .reactivesocket .reactivestreams .extensions .internal .ValidatingSubscription ;
27
30
import io .reactivesocket .reactivestreams .extensions .internal .processors .ConnectableUnicastProcessor ;
28
31
import io .reactivesocket .reactivestreams .extensions .internal .subscribers .CancellableSubscriber ;
29
32
import io .reactivesocket .reactivestreams .extensions .internal .subscribers .Subscribers ;
@@ -50,8 +53,8 @@ public class ClientReactiveSocket implements ReactiveSocket {
50
53
private final StreamIdSupplier streamIdSupplier ;
51
54
private final KeepAliveProvider keepAliveProvider ;
52
55
53
- private final Int2ObjectHashMap <Processor < Frame , Frame > > senders ;
54
- private final Int2ObjectHashMap <Subscriber <? super Payload >> receivers ;
56
+ private final Int2ObjectHashMap <Subscription > senders ;
57
+ private final Int2ObjectHashMap <Subscriber <Frame >> receivers ;
55
58
56
59
private volatile Subscription transportReceiveSubscription ;
57
60
private CancellableSubscriber <Void > keepAliveSendSub ;
@@ -81,86 +84,37 @@ public Publisher<Void> fireAndForget(Payload payload) {
81
84
}
82
85
}
83
86
87
+ @ Override
84
88
public Publisher <Payload > requestResponse (Payload payload ) {
85
89
final int streamId = nextStreamId ();
86
90
final Frame requestFrame = Frame .Request .from (streamId , FrameType .REQUEST_RESPONSE , payload , 1 );
87
91
88
- return doSendReceive (Px .just (requestFrame ), streamId , 1 , false );
92
+ return handleRequestResponse (Px .just (requestFrame ), streamId , 1 , false );
89
93
}
90
94
91
95
@ Override
92
96
public Publisher <Payload > requestStream (Payload payload ) {
93
97
final int streamId = nextStreamId ();
94
98
final Frame requestFrame = Frame .Request .from (streamId , FrameType .REQUEST_STREAM , payload , 1 );
95
99
96
- return doSendReceive (Px .just (requestFrame ), streamId , 1 , true );
100
+ return handleStreamResponse (Px .just (requestFrame ), streamId );
97
101
}
98
102
99
103
@ Override
100
104
public Publisher <Payload > requestSubscription (Payload payload ) {
101
105
final int streamId = nextStreamId ();
102
106
final Frame requestFrame = Frame .Request .from (streamId , FrameType .REQUEST_SUBSCRIPTION , payload , 1 );
103
107
104
- return doSendReceive (Px .just (requestFrame ), streamId , 1 , true );
108
+ return handleStreamResponse (Px .just (requestFrame ), streamId );
105
109
}
106
110
107
111
@ Override
108
112
public Publisher <Payload > requestChannel (Publisher <Payload > payloads ) {
109
113
final int streamId = nextStreamId ();
110
- Px <Frame > frames = Px
111
- .from (payloads )
112
- .map (payload -> Frame .Request .from (streamId , FrameType .REQUEST_CHANNEL , payload , 1 ));
113
- return doSendReceive (frames , streamId , 1 , true );
114
- }
115
-
116
- private Publisher <Payload > doSendReceive (final Publisher <Frame > payload , final int streamId , final int initialRequestN , final boolean sendRequestN ) {
117
- ConnectableUnicastProcessor <Frame > sender = new ConnectableUnicastProcessor <>();
118
-
119
- synchronized (this ) {
120
- senders .put (streamId , sender );
121
- }
122
-
123
- final Runnable cleanup = () -> {
124
- synchronized (this ) {
125
- receivers .remove (streamId );
126
- senders .remove (streamId );
127
- }
128
- };
129
-
130
- return Px
131
- .<Payload >create (subscriber -> {
132
- synchronized (this ) {
133
- receivers .put (streamId , subscriber );
134
- }
135
-
136
- payload .subscribe (sender );
137
-
138
- subscriber .onSubscribe (new Subscription () {
139
-
140
- @ Override
141
- public void request (long n ) {
142
- if (sendRequestN ) {
143
- sender .onNext (Frame .RequestN .from (streamId , n ));
144
- }
145
- }
146
-
147
- @ Override
148
- public void cancel () {
149
- sender .onNext (Frame .Cancel .from (streamId ));
150
- sender .cancel ();
151
- }
152
- });
153
-
154
- try {
155
- Px .from (connection .send (sender ))
156
- .doOnError (th -> subscriber .onError (th ))
157
- .subscribe (DefaultSubscriber .defaultInstance ());
158
- } catch (Throwable t ) {
159
- subscriber .onError (t );
160
- }
161
- })
162
- .doOnRequest (subscription -> sender .start (initialRequestN ))
163
- .doOnTerminate (cleanup );
114
+ return handleStreamResponse (Px .from (payloads )
115
+ .map (payload -> {
116
+ return Frame .Request .from (streamId , FrameType .REQUEST_CHANNEL , payload , 1 );
117
+ }), streamId );
164
118
}
165
119
166
120
@ Override
@@ -194,6 +148,79 @@ public ClientReactiveSocket start(Consumer<Lease> leaseConsumer) {
194
148
return this ;
195
149
}
196
150
151
+ private Publisher <Payload > handleRequestResponse (final Publisher <Frame > payload , final int streamId ,
152
+ final int initialRequestN , final boolean sendRequestN ) {
153
+ ConnectableUnicastProcessor <Frame > sender = new ConnectableUnicastProcessor <>();
154
+
155
+ synchronized (this ) {
156
+ senders .put (streamId , sender );
157
+ }
158
+
159
+ final Runnable cleanup = () -> {
160
+ synchronized (this ) {
161
+ receivers .remove (streamId );
162
+ senders .remove (streamId );
163
+ }
164
+ };
165
+
166
+ return Px
167
+ .<Payload >create (subscriber -> {
168
+ @ SuppressWarnings ("rawtypes" )
169
+ Subscriber raw = subscriber ;
170
+ @ SuppressWarnings ("unchecked" )
171
+ Subscriber <Frame > fs = raw ;
172
+ synchronized (this ) {
173
+ receivers .put (streamId , fs );
174
+ }
175
+
176
+ payload .subscribe (sender );
177
+
178
+ subscriber .onSubscribe (new Subscription () {
179
+
180
+ @ Override
181
+ public void request (long n ) {
182
+ if (sendRequestN ) {
183
+ sender .onNext (Frame .RequestN .from (streamId , n ));
184
+ }
185
+ }
186
+
187
+ @ Override
188
+ public void cancel () {
189
+ sender .onNext (Frame .Cancel .from (streamId ));
190
+ sender .cancel ();
191
+ }
192
+ });
193
+
194
+ Px .from (connection .send (sender ))
195
+ .doOnError (th -> subscriber .onError (th ))
196
+ .subscribe (DefaultSubscriber .defaultInstance ());
197
+
198
+ })
199
+ .doOnRequest (subscription -> sender .start (initialRequestN ))
200
+ .doOnTerminate (cleanup );
201
+ }
202
+
203
+ private Publisher <Payload > handleStreamResponse (Publisher <Frame > request , final int streamId ) {
204
+ RemoteSender sender = new RemoteSender (request , () -> senders .remove (streamId ), streamId , 1 );
205
+ Publisher <Frame > src = s -> {
206
+ CancellableSubscriber <Void > sendSub = doOnError (throwable -> {
207
+ s .onError (throwable );
208
+ });
209
+ ValidatingSubscription <? super Frame > sub = ValidatingSubscription .create (s , () -> {
210
+ sendSub .cancel ();
211
+ }, requestN -> {
212
+ transportReceiveSubscription .request (requestN );
213
+ });
214
+ connection .send (sender ).subscribe (sendSub );
215
+ s .onSubscribe (sub );
216
+ };
217
+
218
+ RemoteReceiver receiver = new RemoteReceiver (src , connection , streamId , () -> receivers .remove (streamId ), true );
219
+ senders .put (streamId , sender );
220
+ receivers .put (streamId , receiver );
221
+ return receiver ;
222
+ }
223
+
197
224
private void startKeepAlive () {
198
225
keepAliveSendSub = doOnError (errorConsumer );
199
226
connection .send (Px .from (keepAliveProvider .ticks ())
@@ -254,7 +281,7 @@ private void handleStreamZero(FrameType type, Frame frame) {
254
281
255
282
@ SuppressWarnings ("unchecked" )
256
283
private void handleFrame (int streamId , FrameType type , Frame frame ) {
257
- Subscriber <? super Payload > receiver ;
284
+ Subscriber <Frame > receiver ;
258
285
synchronized (this ) {
259
286
receiver = receivers .get (streamId );
260
287
}
@@ -270,13 +297,13 @@ private void handleFrame(int streamId, FrameType type, Frame frame) {
270
297
receiver .onComplete ();
271
298
break ;
272
299
case CANCEL : {
273
- Processor sender ;
274
- synchronized (ClientReactiveSocket . this ) {
300
+ Subscription sender ;
301
+ synchronized (this ) {
275
302
sender = senders .remove (streamId );
276
303
receivers .remove (streamId );
277
304
}
278
305
if (sender != null ) {
279
- (( ConnectableUnicastProcessor ) sender ) .cancel ();
306
+ sender .cancel ();
280
307
}
281
308
receiver .onError (new CancelException ("cancelling stream id " + streamId ));
282
309
break ;
@@ -285,13 +312,13 @@ private void handleFrame(int streamId, FrameType type, Frame frame) {
285
312
receiver .onNext (frame );
286
313
break ;
287
314
case REQUEST_N : {
288
- Processor sender ;
289
- synchronized (ClientReactiveSocket . this ) {
315
+ Subscription sender ;
316
+ synchronized (this ) {
290
317
sender = senders .get (streamId );
291
318
}
292
319
if (sender != null ) {
293
320
int n = Frame .RequestN .requestN (frame );
294
- (( ConnectableUnicastProcessor ) sender ). requestMore (n );
321
+ sender . request (n );
295
322
}
296
323
break ;
297
324
}
0 commit comments