Skip to content

Commit 43d44ee

Browse files
committed
optimize request channel to let you peak at the first item in the requestChannel
1 parent f46908f commit 43d44ee

File tree

2 files changed

+94
-37
lines changed

2 files changed

+94
-37
lines changed

rsocket-core/src/main/java/io/rsocket/RSocketServer.java

Lines changed: 75 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@
2727
import org.reactivestreams.Subscriber;
2828
import org.reactivestreams.Subscription;
2929
import reactor.core.Disposable;
30-
import reactor.core.publisher.*;
30+
import reactor.core.publisher.Flux;
31+
import reactor.core.publisher.Mono;
32+
import reactor.core.publisher.SignalType;
33+
import reactor.core.publisher.UnicastProcessor;
3134

3235
import java.util.Collections;
3336
import java.util.Map;
@@ -39,15 +42,17 @@
3942
import static io.rsocket.frame.FrameHeaderFlyweight.FLAGS_M;
4043

4144
/** Server side RSocket. Receives {@link Frame}s from a {@link RSocketClient} */
42-
class RSocketServer implements RSocket {
45+
class RSocketServer implements RequestHandler {
4346

4447
private final DuplexConnection connection;
4548
private final RSocket requestHandler;
49+
private final RequestHandler optimizedRequestHandler;
50+
private final boolean hasOptimizedRequestHandler;
4651
private final Function<Frame, ? extends Payload> frameDecoder;
4752
private final Consumer<Throwable> errorConsumer;
4853

4954
private final Map<Integer, Subscription> sendingSubscriptions;
50-
private final Map<Integer, Processor<Payload,Payload>> channelProcessors;
55+
private final Map<Integer, Processor<Payload, Payload>> channelProcessors;
5156

5257
private final UnboundedProcessor<Frame> sendProcessor;
5358
private KeepAliveHandler keepAliveHandler;
@@ -69,12 +74,22 @@ class RSocketServer implements RSocket {
6974
Consumer<Throwable> errorConsumer,
7075
long tickPeriod,
7176
long ackTimeout) {
77+
78+
if (requestHandler instanceof RequestHandler) {
79+
this.optimizedRequestHandler = (RequestHandler) requestHandler;
80+
this.hasOptimizedRequestHandler = true;
81+
this.requestHandler = null;
82+
} else {
83+
this.hasOptimizedRequestHandler = false;
84+
this.requestHandler = requestHandler;
85+
this.optimizedRequestHandler = null;
86+
}
87+
7288
this.connection = connection;
73-
this.requestHandler = requestHandler;
7489
this.frameDecoder = frameDecoder;
7590
this.errorConsumer = errorConsumer;
7691
this.sendingSubscriptions = Collections.synchronizedMap(new IntObjectHashMap<>());
77-
this.channelProcessors = Collections.synchronizedMap(new IntObjectHashMap<>());
92+
this.channelProcessors = Collections.synchronizedMap(new IntObjectHashMap<>());
7893

7994
// DO NOT Change the order here. The Send processor must be subscribed to before receiving
8095
// connections
@@ -116,43 +131,55 @@ class RSocketServer implements RSocket {
116131
}
117132

118133
private void handleSendProcessorError(Throwable t) {
119-
sendingSubscriptions.values().forEach(subscription -> {
120-
try {
121-
subscription.cancel();
122-
} catch (Throwable e) {
123-
errorConsumer.accept(e);
124-
}
125-
});
134+
sendingSubscriptions
135+
.values()
136+
.forEach(
137+
subscription -> {
138+
try {
139+
subscription.cancel();
140+
} catch (Throwable e) {
141+
errorConsumer.accept(e);
142+
}
143+
});
126144

127-
channelProcessors.values().forEach(subscription -> {
128-
try {
129-
subscription.onError(t);
130-
} catch (Throwable e) {
131-
errorConsumer.accept(e);
132-
}
133-
});
145+
channelProcessors
146+
.values()
147+
.forEach(
148+
subscription -> {
149+
try {
150+
subscription.onError(t);
151+
} catch (Throwable e) {
152+
errorConsumer.accept(e);
153+
}
154+
});
134155
}
135156

136157
private void handleSendProcessorCancel(SignalType t) {
137158
if (SignalType.ON_ERROR == t) {
138159
return;
139160
}
140161

141-
sendingSubscriptions.values().forEach(subscription -> {
142-
try {
143-
subscription.cancel();
144-
} catch (Throwable e) {
145-
errorConsumer.accept(e);
146-
}
147-
});
162+
sendingSubscriptions
163+
.values()
164+
.forEach(
165+
subscription -> {
166+
try {
167+
subscription.cancel();
168+
} catch (Throwable e) {
169+
errorConsumer.accept(e);
170+
}
171+
});
148172

149-
channelProcessors.values().forEach(subscription -> {
150-
try {
151-
subscription.onComplete();
152-
} catch (Throwable e) {
153-
errorConsumer.accept(e);
154-
}
155-
});
173+
channelProcessors
174+
.values()
175+
.forEach(
176+
subscription -> {
177+
try {
178+
subscription.onComplete();
179+
} catch (Throwable e) {
180+
errorConsumer.accept(e);
181+
}
182+
});
156183
}
157184

158185
@Override
@@ -191,6 +218,15 @@ public Flux<Payload> requestChannel(Publisher<Payload> payloads) {
191218
}
192219
}
193220

221+
@Override
222+
public Flux<Payload> requestChannel(Payload payload, Publisher<Payload> payloads) {
223+
try {
224+
return optimizedRequestHandler.requestChannel(payloads);
225+
} catch (Throwable t) {
226+
return Flux.error(t);
227+
}
228+
}
229+
194230
@Override
195231
public Mono<Void> metadataPush(Payload payload) {
196232
try {
@@ -232,9 +268,7 @@ private synchronized void cleanUpSendingSubscriptions() {
232268
}
233269

234270
private synchronized void cleanUpChannelProcessors() {
235-
channelProcessors
236-
.values()
237-
.forEach(Processor::onComplete);
271+
channelProcessors.values().forEach(Processor::onComplete);
238272
channelProcessors.clear();
239273
}
240274

@@ -381,7 +415,11 @@ private void handleChannel(int streamId, Payload payload, int initialRequestN) {
381415
// and any later payload can be processed
382416
frames.onNext(payload);
383417

384-
handleStream(streamId, requestChannel(payloads), initialRequestN);
418+
if (hasOptimizedRequestHandler) {
419+
handleStream(streamId, requestChannel(payload, payloads), initialRequestN);
420+
} else {
421+
handleStream(streamId, requestChannel(payloads), initialRequestN);
422+
}
385423
}
386424

387425
private void handleKeepAliveFrame(Frame frame) {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package io.rsocket;
2+
3+
import org.reactivestreams.Publisher;
4+
import reactor.core.publisher.Flux;
5+
6+
/**
7+
* Extends the {@link RSocket} that allows an implementor to peek at the first request payload of a channel.
8+
*/
9+
public interface RequestHandler extends RSocket {
10+
/**
11+
* Implement this method to peak at the first payload of the incoming request stream
12+
* @param payload First payload in the stream
13+
* @param payloads Stream of request payloads.
14+
* @return Stream of response payloads.
15+
*/
16+
default Flux<Payload> requestChannel(Payload payload, Publisher<Payload> payloads) {
17+
return requestChannel(payloads);
18+
}
19+
}

0 commit comments

Comments
 (0)