16
16
17
17
package io .rsocket ;
18
18
19
- import static io .rsocket .util .ExceptionUtil .noStacktrace ;
20
-
21
19
import io .netty .buffer .Unpooled ;
22
- import io .netty .util .collection .IntObjectHashMap ;
23
20
import io .rsocket .exceptions .ConnectionException ;
24
21
import io .rsocket .exceptions .Exceptions ;
25
22
import io .rsocket .internal .LimitableRequestPublisher ;
26
23
import io .rsocket .internal .UnboundedProcessor ;
27
- import java .nio .channels .ClosedChannelException ;
24
+ import io .rsocket .util .NonBlockingHashMapLong ;
25
+ import org .reactivestreams .Publisher ;
26
+ import org .reactivestreams .Subscriber ;
27
+ import reactor .core .Disposable ;
28
+ import reactor .core .publisher .*;
29
+
30
+ import javax .annotation .Nullable ;
28
31
import java .time .Duration ;
29
32
import java .util .Collection ;
30
33
import java .util .concurrent .atomic .AtomicBoolean ;
31
34
import java .util .concurrent .atomic .AtomicInteger ;
32
35
import java .util .function .Consumer ;
33
36
import java .util .function .Function ;
34
37
import java .util .function .Supplier ;
35
- import javax .annotation .Nullable ;
36
- import org .reactivestreams .Publisher ;
37
- import org .reactivestreams .Subscriber ;
38
- import reactor .core .Disposable ;
39
- import reactor .core .publisher .*;
40
38
41
39
/** Client Side of a RSocket socket. Sends {@link Frame}s to a {@link RSocketServer} */
42
40
class RSocketClient implements RSocket {
43
41
44
- private static final ClosedChannelException CLOSED_CHANNEL_EXCEPTION =
45
- noStacktrace (new ClosedChannelException ());
46
-
47
42
private final DuplexConnection connection ;
48
43
private final Function <Frame , ? extends Payload > frameDecoder ;
49
44
private final Consumer <Throwable > errorConsumer ;
50
45
private final StreamIdSupplier streamIdSupplier ;
51
46
private final MonoProcessor <Void > started ;
52
- private final IntObjectHashMap <LimitableRequestPublisher > senders ;
53
- private final IntObjectHashMap < Subscriber <Payload >> receivers ;
47
+ private final NonBlockingHashMapLong <LimitableRequestPublisher > senders ;
48
+ private final NonBlockingHashMapLong < UnicastProcessor <Payload >> receivers ;
54
49
private final AtomicInteger missedAckCounter ;
55
50
56
51
private final UnboundedProcessor <Frame > sendProcessor ;
@@ -80,8 +75,8 @@ class RSocketClient implements RSocket {
80
75
this .errorConsumer = errorConsumer ;
81
76
this .streamIdSupplier = streamIdSupplier ;
82
77
this .started = MonoProcessor .create ();
83
- this .senders = new IntObjectHashMap <>(256 , 0.9f );
84
- this .receivers = new IntObjectHashMap <>(256 , 0.9f );
78
+ this .senders = new NonBlockingHashMapLong <>(256 );
79
+ this .receivers = new NonBlockingHashMapLong <>(256 );
85
80
this .missedAckCounter = new AtomicInteger ();
86
81
87
82
// DO NOT Change the order here. The Send processor must be subscribed to before receiving
@@ -127,7 +122,7 @@ class RSocketClient implements RSocket {
127
122
}
128
123
129
124
private void handleSendProcessorError (Throwable t ) {
130
- Collection <Subscriber <Payload >> values ;
125
+ Collection <UnicastProcessor <Payload >> values ;
131
126
Collection <LimitableRequestPublisher > values1 ;
132
127
synchronized (RSocketClient .this ) {
133
128
values = receivers .values ();
@@ -151,7 +146,7 @@ private void handleSendProcessorCancel(SignalType t) {
151
146
if (SignalType .ON_ERROR == t ) {
152
147
return ;
153
148
}
154
- Collection <Subscriber <Payload >> values ;
149
+ Collection <UnicastProcessor <Payload >> values ;
155
150
Collection <LimitableRequestPublisher > values1 ;
156
151
synchronized (RSocketClient .this ) {
157
152
values = receivers .values ();
@@ -222,10 +217,15 @@ public Flux<Payload> requestChannel(Publisher<Payload> payloads) {
222
217
223
218
@ Override
224
219
public Mono <Void > metadataPush (Payload payload ) {
225
- final Frame requestFrame = Frame .Request .from (0 , FrameType .METADATA_PUSH , payload , 1 );
226
- payload .release ();
227
- sendProcessor .onNext (requestFrame );
228
- return Mono .empty ();
220
+ Mono <Void > defer =
221
+ Mono .fromRunnable (
222
+ () -> {
223
+ final Frame requestFrame = Frame .Request .from (0 , FrameType .METADATA_PUSH , payload , 1 );
224
+ payload .release ();
225
+ sendProcessor .onNext (requestFrame );
226
+ });
227
+
228
+ return started .then (defer );
229
229
}
230
230
231
231
@ Override
@@ -303,7 +303,7 @@ private Mono<Payload> handleRequestResponse(final Payload payload) {
303
303
Frame .Request .from (streamId , FrameType .REQUEST_RESPONSE , payload , 1 );
304
304
payload .release ();
305
305
306
- MonoProcessor <Payload > receiver = MonoProcessor .create ();
306
+ UnicastProcessor <Payload > receiver = UnicastProcessor .create ();
307
307
308
308
synchronized (this ) {
309
309
receivers .put (streamId , receiver );
@@ -312,6 +312,7 @@ private Mono<Payload> handleRequestResponse(final Payload payload) {
312
312
sendProcessor .onNext (requestFrame );
313
313
314
314
return receiver
315
+ .singleOrEmpty ()
315
316
.doOnError (t -> sendProcessor .onNext (Frame .Error .from (streamId , t )))
316
317
.doOnCancel (() -> sendProcessor .onNext (Frame .Cancel .from (streamId )))
317
318
.doFinally (
@@ -438,7 +439,7 @@ private boolean contains(int streamId) {
438
439
439
440
protected void cleanup () {
440
441
try {
441
- Collection <Subscriber <Payload >> subscribers ;
442
+ Collection <UnicastProcessor <Payload >> subscribers ;
442
443
Collection <LimitableRequestPublisher > publishers ;
443
444
synchronized (RSocketClient .this ) {
444
445
subscribers = receivers .values ();
@@ -468,9 +469,9 @@ private synchronized void cleanUpLimitableRequestPublisher(
468
469
}
469
470
}
470
471
471
- private synchronized void cleanUpSubscriber (Subscriber <?> subscriber ) {
472
+ private synchronized void cleanUpSubscriber (UnicastProcessor <?> subscriber ) {
472
473
try {
473
- subscriber .onError ( CLOSED_CHANNEL_EXCEPTION );
474
+ subscriber .cancel ( );
474
475
} catch (Throwable t ) {
475
476
errorConsumer .accept (t );
476
477
}
0 commit comments