Uh oh!
There was an error while loading. Please reload this page.
Implements dedicated Publisher/Subscriber for each request type #761 - #761
Conversation
d71b8c0 to
7aa340bCompare7aa340b to
406daeeCompareOlegDokuka
commented
Mar 30, 2020
BenchesBase Line RC7-SNAPSHOTCurrent Branch |
231cae8 to
a78a14dCompareTesting Matrix ChecklistGeneric
Racing Cases |
a78a14d to
e7efe6dCompare5bd5fcb to
2d6c698CompareThere was a problem hiding this comment.
StreamManager provides a way for requester Mono's and responder Subscriber's to access something back from RSocketRequester and RSocketResponder. This can be taken further to avoid passing other fields as well.
For example RSocketRequester and RSocketResponder could extend this (replacing StreamManager and AbstractStreamManager):
classRequesterResponderSupport {
privatefinalintmtu;
privatefinalintmaxFrameLength;
privatefinalintmaxInboundPayloadSize;
privatefinalPayloadDecoderpayloadDecoder;
privatefinalByteBufAllocatorallocator;
@NullablefinalStreamIdSupplierstreamIdSupplier;
finalIntObjectMap<FrameHandler> activeStreams;
privatefinalUnboundedProcessor<ByteBuf> sendProcessor;
publicRequesterResponderSupport(
intmtu,
intmaxFrameLength,
intmaxInboundPayloadSize,
PayloadDecoderpayloadDecoder,
ByteBufAllocatorallocator,
@NullableStreamIdSupplierstreamIdSupplier,
IntObjectMap<FrameHandler> activeStreams) {
this.activeStreams = activeStreams;
this.mtu = mtu;
this.maxFrameLength = maxFrameLength;
this.maxInboundPayloadSize = maxInboundPayloadSize;
this.payloadDecoder = payloadDecoder;
this.allocator = allocator;
this.streamIdSupplier = streamIdSupplier;
this.sendProcessor = newUnboundedProcessor<>();
}
publicintgetMtu() {
returnmtu;
}
publicintgetMaxFrameLength() {
returnmaxFrameLength;
}
publicintgetMaxInboundPayloadSize() {
returnmaxInboundPayloadSize;
}
publicPayloadDecodergetPayloadDecoder() {
returnpayloadDecoder;
}
publicByteBufAllocatorgetAllocator() {
returnallocator;
}
publicUnboundedProcessor<ByteBuf> getSendProcessor() {
returnsendProcessor;
}
publicsynchronizedintgetNextId() {
if (this.streamIdSupplier != null) {
returnthis.streamIdSupplier.nextStreamId(this.activeStreams);
}
else {
thrownewUnsupportedOperationException("Responder can not issue id");
}
}
publicsynchronizedintaddAndGetNextId(FrameHandlerframeHandler) {
if (this.streamIdSupplier != null) {
finalIntObjectMap<FrameHandler> activeStreams = this.activeStreams;
finalintstreamId = this.streamIdSupplier.nextStreamId(activeStreams);
activeStreams.put(streamId, frameHandler);
returnstreamId;
}
else {
thrownewUnsupportedOperationException("Responder can not issue id");
}
}
publicFrameHandlerget(intstreamId) {
returnthis.activeStreams.get(streamId);
}
publicbooleanremove(intstreamId, FrameHandlerframeHandler) {
returnthis.activeStreams.remove(streamId, frameHandler);
}
}Now the requester Mono's and Flux's can be created more easily:
@OverridepublicFlux<Payload> requestStream(Payloadpayload) {
returnnewRequestStreamFlux(payload, this);
}Likewise for responder Subscriber's:
RequestResponseSubscribersubscriber = newRequestResponseSubscriber(streamId, frame, this);There might be other opportunities for re-use as well through such a common base class.
f86226d to
eaeb099CompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| AtomicLongFieldUpdater<T> updater, | ||
| T instance, | ||
| ReassembledFramesHolder reassembledFramesHolder, | ||
| Subscription subscription, |
There was a problem hiding this comment.
The subscription is the RequesterFrameHandler instance. Why don't we add cancel() to RequesterFrameHandler or have it extend Subscription so that only RequesterFrameHandler is passed in, making it easier to understand where cancel() is handled?
There was a problem hiding this comment.
The idea is to avoid mixing RSocket spec frame handling with the reactive streams. First of all, it makes it impossible to understand from where method was invoked, especially when it comes to requestChannel case. Initially, it was reactive streams interfaces, but after lots of issues with understanding where and how should I handle every call (depends on the inbound vs outbound) I decided to get rid of that idea and make things fully separate
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| final Payload p = this.payload; | ||
| try { | ||
| if (!isValid(this.mtu, this.maxFrameLength, p, false)) { | ||
| lazyTerminate(STATE, this); | ||
| Operators.error( | ||
| actual, | ||
| new IllegalArgumentException( | ||
| String.format(INVALID_PAYLOAD_ERROR_MESSAGE, this.maxFrameLength))); | ||
| p.release(); | ||
| return; | ||
| } | ||
| } catch (IllegalReferenceCountException e) { | ||
| lazyTerminate(STATE, this); | ||
| Operators.error(actual, e); | ||
| return; | ||
| } |
There was a problem hiding this comment.
Couldn't the payload be validated before subscription, basically as soon as it is provided? Maybe RSocketRequester could hold this logic and make the check before creating a requester Mono/Flux, thus also re-using the logic.
There was a problem hiding this comment.
In any case, it is going to be code duplication. The only different - that code would be in a different place. Thus, once something needed to be adjusted - we would need to look at more places and not only to Requester / Responder operators
Uh oh!
There was an error while loading. Please reload this page.
simonbasle
left a comment
There was a problem hiding this comment.
I didn't dig far deeper after yesterday's live review. it seems @rstoyanchev has already spotted quite a few elements to improve. overall I'd try to add more comments and documentations, especially on utils classes (like what's been done in StateUtils 👍)
Uh oh!
There was an error while loading. Please reload this page.
eaeb099 to
e3b7998Compare93f9d5c to
2854e04CompareOlegDokuka
commented
Jul 29, 2020
Done. Ready for another round of review |
c531667 to
0b63bbfCompareOlegDokuka
commented
Jul 29, 2020
Applied most of requested changes. Will be merging this one. More polishing can be done in the followups to this PR |
Signed-off-by: Oleh Dokuka <shadowgun@i.ua>
0b63bbf to
8be980eComparePublisher/Subscriber for each request typePublisher/Subscriber for each request typePublisher/Subscriber for each request type #761
This PR provides fully reworked internals for all possible interactions for Rsocket requester and responder
fixes#742#641#613#641#760