io.rsocket.core.RequesterResponderSupport Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rsocket-core Show documentation
Show all versions of rsocket-core Show documentation
Core functionality for the RSocket library
The newest version!
package io.rsocket.core;
import io.netty.buffer.ByteBufAllocator;
import io.netty.util.collection.IntObjectHashMap;
import io.netty.util.collection.IntObjectMap;
import io.rsocket.DuplexConnection;
import io.rsocket.RSocket;
import io.rsocket.frame.decoder.PayloadDecoder;
import io.rsocket.plugins.RequestInterceptor;
import java.util.Objects;
import java.util.function.Function;
import reactor.util.annotation.Nullable;
class RequesterResponderSupport {
private final int mtu;
private final int maxFrameLength;
private final int maxInboundPayloadSize;
private final PayloadDecoder payloadDecoder;
private final ByteBufAllocator allocator;
private final DuplexConnection connection;
@Nullable private final RequestInterceptor requestInterceptor;
@Nullable final StreamIdSupplier streamIdSupplier;
final IntObjectMap activeStreams;
public RequesterResponderSupport(
int mtu,
int maxFrameLength,
int maxInboundPayloadSize,
PayloadDecoder payloadDecoder,
DuplexConnection connection,
@Nullable StreamIdSupplier streamIdSupplier,
Function requestInterceptorFunction) {
this.activeStreams = new IntObjectHashMap<>();
this.mtu = mtu;
this.maxFrameLength = maxFrameLength;
this.maxInboundPayloadSize = maxInboundPayloadSize;
this.payloadDecoder = payloadDecoder;
this.allocator = connection.alloc();
this.streamIdSupplier = streamIdSupplier;
this.connection = connection;
this.requestInterceptor = requestInterceptorFunction.apply((RSocket) this);
}
public int getMtu() {
return mtu;
}
public int getMaxFrameLength() {
return maxFrameLength;
}
public int getMaxInboundPayloadSize() {
return maxInboundPayloadSize;
}
public PayloadDecoder getPayloadDecoder() {
return payloadDecoder;
}
public ByteBufAllocator getAllocator() {
return allocator;
}
public DuplexConnection getDuplexConnection() {
return connection;
}
@Nullable
public RequesterLeaseTracker getRequesterLeaseTracker() {
return null;
}
@Nullable
public RequestInterceptor getRequestInterceptor() {
return requestInterceptor;
}
/**
* Issues next {@code streamId}
*
* @return issued {@code streamId}
* @throws RuntimeException if the {@link RequesterResponderSupport} is terminated for any reason
*/
public int getNextStreamId() {
final StreamIdSupplier streamIdSupplier = this.streamIdSupplier;
if (streamIdSupplier != null) {
synchronized (this) {
return streamIdSupplier.nextStreamId(this.activeStreams);
}
} else {
throw new UnsupportedOperationException("Responder can not issue id");
}
}
/**
* Adds frameHandler and returns issued {@code streamId} back
*
* @param frameHandler to store
* @return issued {@code streamId}
* @throws RuntimeException if the {@link RequesterResponderSupport} is terminated for any reason
*/
public int addAndGetNextStreamId(FrameHandler frameHandler) {
final StreamIdSupplier streamIdSupplier = this.streamIdSupplier;
if (streamIdSupplier != null) {
final IntObjectMap activeStreams = this.activeStreams;
synchronized (this) {
final int streamId = streamIdSupplier.nextStreamId(activeStreams);
activeStreams.put(streamId, frameHandler);
return streamId;
}
} else {
throw new UnsupportedOperationException("Responder can not issue id");
}
}
public synchronized boolean add(int streamId, FrameHandler frameHandler) {
final IntObjectMap activeStreams = this.activeStreams;
// copy of Map.putIfAbsent(key, value) without `streamId` boxing
final FrameHandler previousHandler = activeStreams.get(streamId);
if (previousHandler == null) {
activeStreams.put(streamId, frameHandler);
return true;
}
return false;
}
/**
* Resolves {@link FrameHandler} by {@code streamId}
*
* @param streamId used to resolve {@link FrameHandler}
* @return {@link FrameHandler} or {@code null}
*/
@Nullable
public synchronized FrameHandler get(int streamId) {
return this.activeStreams.get(streamId);
}
/**
* Removes {@link FrameHandler} if it is present and equals to the given one
*
* @param streamId to lookup for {@link FrameHandler}
* @param frameHandler instance to check with the found one
* @return {@code true} if there is {@link FrameHandler} for the given {@code streamId} and the
* instance equals to the passed one
*/
public synchronized boolean remove(int streamId, FrameHandler frameHandler) {
final IntObjectMap activeStreams = this.activeStreams;
// copy of Map.remove(key, value) without `streamId` boxing
final FrameHandler curValue = activeStreams.get(streamId);
if (!Objects.equals(curValue, frameHandler)) {
return false;
}
activeStreams.remove(streamId);
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy