|
@@ -106,19 +106,15 @@ public abstract class TcpTransport extends AbstractLifecycleComponent implements
|
|
|
private static final long NINETY_PER_HEAP_SIZE = (long) (JvmInfo.jvmInfo().getMem().getHeapMax().getBytes() * 0.9);
|
|
private static final long NINETY_PER_HEAP_SIZE = (long) (JvmInfo.jvmInfo().getMem().getHeapMax().getBytes() * 0.9);
|
|
|
private static final BytesReference EMPTY_BYTES_REFERENCE = new BytesArray(new byte[0]);
|
|
private static final BytesReference EMPTY_BYTES_REFERENCE = new BytesArray(new byte[0]);
|
|
|
|
|
|
|
|
- private final String[] features;
|
|
|
|
|
-
|
|
|
|
|
protected final Settings settings;
|
|
protected final Settings settings;
|
|
|
private final CircuitBreakerService circuitBreakerService;
|
|
private final CircuitBreakerService circuitBreakerService;
|
|
|
- private final Version version;
|
|
|
|
|
protected final ThreadPool threadPool;
|
|
protected final ThreadPool threadPool;
|
|
|
protected final BigArrays bigArrays;
|
|
protected final BigArrays bigArrays;
|
|
|
protected final PageCacheRecycler pageCacheRecycler;
|
|
protected final PageCacheRecycler pageCacheRecycler;
|
|
|
protected final NetworkService networkService;
|
|
protected final NetworkService networkService;
|
|
|
protected final Set<ProfileSettings> profileSettings;
|
|
protected final Set<ProfileSettings> profileSettings;
|
|
|
|
|
|
|
|
- private static final TransportMessageListener NOOP_LISTENER = new TransportMessageListener() {};
|
|
|
|
|
- private volatile TransportMessageListener messageListener = NOOP_LISTENER;
|
|
|
|
|
|
|
+ private volatile TransportMessageListener messageListener = TransportMessageListener.NOOP_LISTENER;
|
|
|
|
|
|
|
|
private final ConcurrentMap<String, BoundTransportAddress> profileBoundAddresses = newConcurrentMap();
|
|
private final ConcurrentMap<String, BoundTransportAddress> profileBoundAddresses = newConcurrentMap();
|
|
|
private final Map<String, List<TcpServerChannel>> serverChannels = newConcurrentMap();
|
|
private final Map<String, List<TcpServerChannel>> serverChannels = newConcurrentMap();
|
|
@@ -137,34 +133,23 @@ public abstract class TcpTransport extends AbstractLifecycleComponent implements
|
|
|
private final TransportKeepAlive keepAlive;
|
|
private final TransportKeepAlive keepAlive;
|
|
|
private final InboundMessage.Reader reader;
|
|
private final InboundMessage.Reader reader;
|
|
|
private final OutboundHandler outboundHandler;
|
|
private final OutboundHandler outboundHandler;
|
|
|
- private final String nodeName;
|
|
|
|
|
|
|
|
|
|
public TcpTransport(Settings settings, Version version, ThreadPool threadPool, PageCacheRecycler pageCacheRecycler,
|
|
public TcpTransport(Settings settings, Version version, ThreadPool threadPool, PageCacheRecycler pageCacheRecycler,
|
|
|
CircuitBreakerService circuitBreakerService, NamedWriteableRegistry namedWriteableRegistry,
|
|
CircuitBreakerService circuitBreakerService, NamedWriteableRegistry namedWriteableRegistry,
|
|
|
NetworkService networkService) {
|
|
NetworkService networkService) {
|
|
|
this.settings = settings;
|
|
this.settings = settings;
|
|
|
this.profileSettings = getProfileSettings(settings);
|
|
this.profileSettings = getProfileSettings(settings);
|
|
|
- this.version = version;
|
|
|
|
|
this.threadPool = threadPool;
|
|
this.threadPool = threadPool;
|
|
|
this.bigArrays = new BigArrays(pageCacheRecycler, circuitBreakerService, CircuitBreaker.IN_FLIGHT_REQUESTS);
|
|
this.bigArrays = new BigArrays(pageCacheRecycler, circuitBreakerService, CircuitBreaker.IN_FLIGHT_REQUESTS);
|
|
|
this.pageCacheRecycler = pageCacheRecycler;
|
|
this.pageCacheRecycler = pageCacheRecycler;
|
|
|
this.circuitBreakerService = circuitBreakerService;
|
|
this.circuitBreakerService = circuitBreakerService;
|
|
|
this.networkService = networkService;
|
|
this.networkService = networkService;
|
|
|
this.transportLogger = new TransportLogger();
|
|
this.transportLogger = new TransportLogger();
|
|
|
- this.outboundHandler = new OutboundHandler(threadPool, bigArrays, transportLogger);
|
|
|
|
|
- this.handshaker = new TransportHandshaker(version, threadPool,
|
|
|
|
|
- (node, channel, requestId, v) -> sendRequestToChannel(node, channel, requestId,
|
|
|
|
|
- TransportHandshaker.HANDSHAKE_ACTION_NAME, new TransportHandshaker.HandshakeRequest(version),
|
|
|
|
|
- TransportRequestOptions.EMPTY, v, false, true),
|
|
|
|
|
- (v, features, channel, response, requestId) -> sendResponse(v, features, channel, response, requestId,
|
|
|
|
|
- TransportHandshaker.HANDSHAKE_ACTION_NAME, false, true));
|
|
|
|
|
- this.keepAlive = new TransportKeepAlive(threadPool, this.outboundHandler::sendBytes);
|
|
|
|
|
- this.reader = new InboundMessage.Reader(version, namedWriteableRegistry, threadPool.getThreadContext());
|
|
|
|
|
- this.nodeName = Node.NODE_NAME_SETTING.get(settings);
|
|
|
|
|
-
|
|
|
|
|
|
|
+ String nodeName = Node.NODE_NAME_SETTING.get(settings);
|
|
|
final Settings defaultFeatures = TransportSettings.DEFAULT_FEATURES_SETTING.get(settings);
|
|
final Settings defaultFeatures = TransportSettings.DEFAULT_FEATURES_SETTING.get(settings);
|
|
|
|
|
+ String[] features;
|
|
|
if (defaultFeatures == null) {
|
|
if (defaultFeatures == null) {
|
|
|
- this.features = new String[0];
|
|
|
|
|
|
|
+ features = new String[0];
|
|
|
} else {
|
|
} else {
|
|
|
defaultFeatures.names().forEach(key -> {
|
|
defaultFeatures.names().forEach(key -> {
|
|
|
if (Booleans.parseBoolean(defaultFeatures.get(key)) == false) {
|
|
if (Booleans.parseBoolean(defaultFeatures.get(key)) == false) {
|
|
@@ -172,8 +157,18 @@ public abstract class TcpTransport extends AbstractLifecycleComponent implements
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
// use a sorted set to present the features in a consistent order
|
|
// use a sorted set to present the features in a consistent order
|
|
|
- this.features = new TreeSet<>(defaultFeatures.names()).toArray(new String[defaultFeatures.names().size()]);
|
|
|
|
|
|
|
+ features = new TreeSet<>(defaultFeatures.names()).toArray(new String[defaultFeatures.names().size()]);
|
|
|
}
|
|
}
|
|
|
|
|
+ this.outboundHandler = new OutboundHandler(nodeName, version, features, threadPool, bigArrays, transportLogger);
|
|
|
|
|
+
|
|
|
|
|
+ this.handshaker = new TransportHandshaker(version, threadPool,
|
|
|
|
|
+ (node, channel, requestId, v) -> outboundHandler.sendRequest(node, channel, requestId,
|
|
|
|
|
+ TransportHandshaker.HANDSHAKE_ACTION_NAME, new TransportHandshaker.HandshakeRequest(version),
|
|
|
|
|
+ TransportRequestOptions.EMPTY, v, false, true),
|
|
|
|
|
+ (v, features1, channel, response, requestId) -> outboundHandler.sendResponse(v, features1, channel, requestId,
|
|
|
|
|
+ TransportHandshaker.HANDSHAKE_ACTION_NAME, response, false, true));
|
|
|
|
|
+ this.keepAlive = new TransportKeepAlive(threadPool, this.outboundHandler::sendBytes);
|
|
|
|
|
+ this.reader = new InboundMessage.Reader(version, namedWriteableRegistry, threadPool.getThreadContext());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -182,8 +177,9 @@ public abstract class TcpTransport extends AbstractLifecycleComponent implements
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public synchronized void setMessageListener(TransportMessageListener listener) {
|
|
public synchronized void setMessageListener(TransportMessageListener listener) {
|
|
|
- if (messageListener == NOOP_LISTENER) {
|
|
|
|
|
|
|
+ if (messageListener == TransportMessageListener.NOOP_LISTENER) {
|
|
|
messageListener = listener;
|
|
messageListener = listener;
|
|
|
|
|
+ outboundHandler.setMessageListener(listener);
|
|
|
} else {
|
|
} else {
|
|
|
throw new IllegalStateException("Cannot set message listener twice");
|
|
throw new IllegalStateException("Cannot set message listener twice");
|
|
|
}
|
|
}
|
|
@@ -267,7 +263,7 @@ public abstract class TcpTransport extends AbstractLifecycleComponent implements
|
|
|
throw new NodeNotConnectedException(node, "connection already closed");
|
|
throw new NodeNotConnectedException(node, "connection already closed");
|
|
|
}
|
|
}
|
|
|
TcpChannel channel = channel(options.type());
|
|
TcpChannel channel = channel(options.type());
|
|
|
- sendRequestToChannel(this.node, channel, requestId, action, request, options, getVersion(), compress);
|
|
|
|
|
|
|
+ outboundHandler.sendRequest(node, channel, requestId, action, request, options, getVersion(), compress, false);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -661,81 +657,6 @@ public abstract class TcpTransport extends AbstractLifecycleComponent implements
|
|
|
*/
|
|
*/
|
|
|
protected abstract void stopInternal();
|
|
protected abstract void stopInternal();
|
|
|
|
|
|
|
|
- private void sendRequestToChannel(final DiscoveryNode node, final TcpChannel channel, final long requestId, final String action,
|
|
|
|
|
- final TransportRequest request, TransportRequestOptions options, Version channelVersion,
|
|
|
|
|
- boolean compressRequest) throws IOException, TransportException {
|
|
|
|
|
- sendRequestToChannel(node, channel, requestId, action, request, options, channelVersion, compressRequest, false);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private void sendRequestToChannel(final DiscoveryNode node, final TcpChannel channel, final long requestId, final String action,
|
|
|
|
|
- final TransportRequest request, TransportRequestOptions options, Version channelVersion,
|
|
|
|
|
- boolean compressRequest, boolean isHandshake) throws IOException, TransportException {
|
|
|
|
|
- Version version = Version.min(this.version, channelVersion);
|
|
|
|
|
- OutboundMessage.Request message = new OutboundMessage.Request(threadPool.getThreadContext(), features, request, version, action,
|
|
|
|
|
- requestId, isHandshake, compressRequest);
|
|
|
|
|
- ActionListener<Void> listener = ActionListener.wrap(() ->
|
|
|
|
|
- messageListener.onRequestSent(node, requestId, action, request, options));
|
|
|
|
|
- outboundHandler.sendMessage(channel, message, listener);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Sends back an error response to the caller via the given channel
|
|
|
|
|
- *
|
|
|
|
|
- * @param nodeVersion the caller node version
|
|
|
|
|
- * @param features the caller features
|
|
|
|
|
- * @param channel the channel to send the response to
|
|
|
|
|
- * @param error the error to return
|
|
|
|
|
- * @param requestId the request ID this response replies to
|
|
|
|
|
- * @param action the action this response replies to
|
|
|
|
|
- */
|
|
|
|
|
- public void sendErrorResponse(
|
|
|
|
|
- final Version nodeVersion,
|
|
|
|
|
- final Set<String> features,
|
|
|
|
|
- final TcpChannel channel,
|
|
|
|
|
- final Exception error,
|
|
|
|
|
- final long requestId,
|
|
|
|
|
- final String action) throws IOException {
|
|
|
|
|
- Version version = Version.min(this.version, nodeVersion);
|
|
|
|
|
- TransportAddress address = new TransportAddress(channel.getLocalAddress());
|
|
|
|
|
- RemoteTransportException tx = new RemoteTransportException(nodeName, address, action, error);
|
|
|
|
|
- OutboundMessage.Response message = new OutboundMessage.Response(threadPool.getThreadContext(), features, tx, version, requestId,
|
|
|
|
|
- false, false);
|
|
|
|
|
- ActionListener<Void> listener = ActionListener.wrap(() -> messageListener.onResponseSent(requestId, action, error));
|
|
|
|
|
- outboundHandler.sendMessage(channel, message, listener);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Sends the response to the given channel. This method should be used to send {@link TransportResponse} objects back to the caller.
|
|
|
|
|
- *
|
|
|
|
|
- * @see #sendErrorResponse(Version, Set, TcpChannel, Exception, long, String) for sending back errors to the caller
|
|
|
|
|
- */
|
|
|
|
|
- public void sendResponse(
|
|
|
|
|
- final Version nodeVersion,
|
|
|
|
|
- final Set<String> features,
|
|
|
|
|
- final TcpChannel channel,
|
|
|
|
|
- final TransportResponse response,
|
|
|
|
|
- final long requestId,
|
|
|
|
|
- final String action,
|
|
|
|
|
- final boolean compress) throws IOException {
|
|
|
|
|
- sendResponse(nodeVersion, features, channel, response, requestId, action, compress, false);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private void sendResponse(
|
|
|
|
|
- final Version nodeVersion,
|
|
|
|
|
- final Set<String> features,
|
|
|
|
|
- final TcpChannel channel,
|
|
|
|
|
- final TransportResponse response,
|
|
|
|
|
- final long requestId,
|
|
|
|
|
- final String action,
|
|
|
|
|
- boolean compress,
|
|
|
|
|
- boolean isHandshake) throws IOException {
|
|
|
|
|
- Version version = Version.min(this.version, nodeVersion);
|
|
|
|
|
- OutboundMessage.Response message = new OutboundMessage.Response(threadPool.getThreadContext(), features, response, version,
|
|
|
|
|
- requestId, isHandshake, compress);
|
|
|
|
|
- ActionListener<Void> listener = ActionListener.wrap(() -> messageListener.onResponseSent(requestId, action, response));
|
|
|
|
|
- outboundHandler.sendMessage(channel, message, listener);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
/**
|
|
/**
|
|
|
* Handles inbound message that has been decoded.
|
|
* Handles inbound message that has been decoded.
|
|
|
*
|
|
*
|
|
@@ -913,7 +834,7 @@ public abstract class TcpTransport extends AbstractLifecycleComponent implements
|
|
|
message.getStoredContext().restore();
|
|
message.getStoredContext().restore();
|
|
|
threadContext.putTransient("_remote_address", remoteAddress);
|
|
threadContext.putTransient("_remote_address", remoteAddress);
|
|
|
if (message.isRequest()) {
|
|
if (message.isRequest()) {
|
|
|
- handleRequest(channel, (InboundMessage.RequestMessage) message, reference.length());
|
|
|
|
|
|
|
+ handleRequest(channel, (InboundMessage.Request) message, reference.length());
|
|
|
} else {
|
|
} else {
|
|
|
final TransportResponseHandler<?> handler;
|
|
final TransportResponseHandler<?> handler;
|
|
|
long requestId = message.getRequestId();
|
|
long requestId = message.getRequestId();
|
|
@@ -999,7 +920,7 @@ public abstract class TcpTransport extends AbstractLifecycleComponent implements
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- protected void handleRequest(TcpChannel channel, InboundMessage.RequestMessage message, int messageLengthBytes) throws IOException {
|
|
|
|
|
|
|
+ protected void handleRequest(TcpChannel channel, InboundMessage.Request message, int messageLengthBytes) throws IOException {
|
|
|
final Set<String> features = message.getFeatures();
|
|
final Set<String> features = message.getFeatures();
|
|
|
final String profileName = channel.getProfile();
|
|
final String profileName = channel.getProfile();
|
|
|
final String action = message.getActionName();
|
|
final String action = message.getActionName();
|
|
@@ -1021,8 +942,8 @@ public abstract class TcpTransport extends AbstractLifecycleComponent implements
|
|
|
} else {
|
|
} else {
|
|
|
getInFlightRequestBreaker().addWithoutBreaking(messageLengthBytes);
|
|
getInFlightRequestBreaker().addWithoutBreaking(messageLengthBytes);
|
|
|
}
|
|
}
|
|
|
- transportChannel = new TcpTransportChannel(this, channel, action, requestId, version, features, profileName,
|
|
|
|
|
- messageLengthBytes, message.isCompress());
|
|
|
|
|
|
|
+ transportChannel = new TcpTransportChannel(outboundHandler, channel, action, requestId, version, features,
|
|
|
|
|
+ circuitBreakerService, messageLengthBytes, message.isCompress());
|
|
|
final TransportRequest request = reg.newRequest(stream);
|
|
final TransportRequest request = reg.newRequest(stream);
|
|
|
request.remoteAddress(new TransportAddress(channel.getRemoteAddress()));
|
|
request.remoteAddress(new TransportAddress(channel.getRemoteAddress()));
|
|
|
// in case we throw an exception, i.e. when the limit is hit, we don't want to verify
|
|
// in case we throw an exception, i.e. when the limit is hit, we don't want to verify
|
|
@@ -1032,8 +953,8 @@ public abstract class TcpTransport extends AbstractLifecycleComponent implements
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
// the circuit breaker tripped
|
|
// the circuit breaker tripped
|
|
|
if (transportChannel == null) {
|
|
if (transportChannel == null) {
|
|
|
- transportChannel = new TcpTransportChannel(this, channel, action, requestId, version, features,
|
|
|
|
|
- profileName, 0, message.isCompress());
|
|
|
|
|
|
|
+ transportChannel = new TcpTransportChannel(outboundHandler, channel, action, requestId, version, features,
|
|
|
|
|
+ circuitBreakerService, 0, message.isCompress());
|
|
|
}
|
|
}
|
|
|
try {
|
|
try {
|
|
|
transportChannel.sendResponse(e);
|
|
transportChannel.sendResponse(e);
|