use of org.apache.ignite.spi.communication.CommunicationListener in project ignite by apache.
the class GridIoManager method send.
/**
* @param node Destination node.
* @param topic Topic to send the message to.
* @param topicOrd GridTopic enumeration ordinal.
* @param msg Message to send.
* @param plc Type of processing.
* @param ordered Ordered flag.
* @param timeout Timeout.
* @param skipOnTimeout Whether message can be skipped on timeout.
* @param ackC Ack closure.
* @param async If {@code true} message for local node will be processed in pool, otherwise in current thread.
* @throws IgniteCheckedException Thrown in case of any errors.
*/
private void send(ClusterNode node, Object topic, int topicOrd, Message msg, byte plc, boolean ordered, long timeout, boolean skipOnTimeout, IgniteInClosure<IgniteException> ackC, boolean async) throws IgniteCheckedException {
assert node != null;
assert topic != null;
assert msg != null;
// Async execution was added only for IgniteMessaging.
assert !async || msg instanceof GridIoUserMessage : msg;
assert topicOrd >= 0 || !(topic instanceof GridTopic) : msg;
try (TraceSurroundings ignored = support(null)) {
MTC.span().addLog(() -> "Create communication msg - " + traceName(msg));
GridIoMessage ioMsg = createGridIoMessage(topic, topicOrd, msg, plc, ordered, timeout, skipOnTimeout);
if (locNodeId.equals(node.id())) {
assert plc != P2P_POOL;
CommunicationListener commLsnr = this.commLsnr;
if (commLsnr == null)
throw new IgniteCheckedException("Trying to send message when grid is not fully started.");
if (ordered)
processOrderedMessage(locNodeId, ioMsg, plc, null);
else if (async)
processRegularMessage(locNodeId, ioMsg, plc, NOOP);
else
processRegularMessage0(ioMsg, locNodeId);
if (ackC != null)
ackC.apply(null);
} else {
if (topicOrd < 0)
ioMsg.topicBytes(U.marshal(marsh, topic));
try {
if ((CommunicationSpi<?>) getSpi() instanceof TcpCommunicationSpi)
getTcpCommunicationSpi().sendMessage(node, ioMsg, ackC);
else
getSpi().sendMessage(node, ioMsg);
} catch (IgniteSpiException e) {
if (e.getCause() instanceof ClusterTopologyCheckedException)
throw (ClusterTopologyCheckedException) e.getCause();
if (!ctx.discovery().alive(node))
throw new ClusterTopologyCheckedException("Failed to send message, node left: " + node.id(), e);
throw new IgniteCheckedException("Failed to send message (node may have left the grid or " + "TCP connection cannot be established due to firewall issues) " + "[node=" + node + ", topic=" + topic + ", msg=" + msg + ", policy=" + plc + ']', e);
}
}
}
}
use of org.apache.ignite.spi.communication.CommunicationListener in project ignite by apache.
the class TcpCommunicationSpi method spiStart.
/**
* {@inheritDoc}
*/
@Override
public void spiStart(String igniteInstanceName) throws IgniteSpiException {
final Function<UUID, ClusterNode> nodeGetter = (nodeId) -> getSpiContext().node(nodeId);
final Supplier<ClusterNode> locNodeSupplier = () -> getSpiContext().localNode();
final Supplier<Ignite> igniteExSupplier = this::ignite;
final Function<UUID, Boolean> pingNode = (nodeId) -> getSpiContext().pingNode(nodeId);
final Supplier<FailureProcessor> failureProcessorSupplier = () -> ignite instanceof IgniteEx ? ((IgniteEx) ignite).context().failure() : null;
final Supplier<Boolean> isStopped = () -> getSpiContext().isStopping();
this.igniteInstanceName = igniteInstanceName;
cfg.failureDetectionTimeout(ignite.configuration().getFailureDetectionTimeout());
attributeNames = new AttributeNames(createSpiAttributeName(ATTR_PAIRED_CONN), createSpiAttributeName(ATTR_ADDRS), createSpiAttributeName(ATTR_HOST_NAMES), createSpiAttributeName(ATTR_EXT_ADDRS), createSpiAttributeName(ATTR_PORT), createSpiAttributeName(ATTR_FORCE_CLIENT_SERVER_CONNECTIONS));
boolean client = Boolean.TRUE.equals(ignite().configuration().isClientMode());
this.stateProvider = new ClusterStateProvider(ignite, locNodeSupplier, this, isStopped, () -> super.getSpiContext(), log, igniteExSupplier);
try {
cfg.localHost(U.resolveLocalHost(cfg.localAddress()));
} catch (IOException e) {
throw new IgniteSpiException("Failed to initialize local address: " + cfg.localAddress(), e);
}
if (cfg.connectionsPerNode() > 1)
connPlc = new RoundRobinConnectionPolicy(cfg);
else
connPlc = new FirstConnectionPolicy();
this.srvLsnr = resolve(ignite, new InboundConnectionHandler(log, cfg, nodeGetter, locNodeSupplier, stateProvider, clientPool, commWorker, connectGate, failureProcessorSupplier, attributeNames, metricsLsnr, nioSrvWrapper, ctxInitLatch, client, igniteExSupplier, new CommunicationListener<Message>() {
@Override
public void onMessage(UUID nodeId, Message msg, IgniteRunnable msgC) {
notifyListener(nodeId, msg, msgC);
}
@Override
public void onDisconnected(UUID nodeId) {
if (lsnr != null)
lsnr.onDisconnected(nodeId);
}
}));
TcpHandshakeExecutor tcpHandshakeExecutor = resolve(ignite, new TcpHandshakeExecutor(log, stateProvider, cfg.directBuffer()));
this.nioSrvWrapper = resolve(ignite, new GridNioServerWrapper(log, cfg, attributeNames, tracing, nodeGetter, locNodeSupplier, connectGate, stateProvider, this::getExceptionRegistry, commWorker, ignite.configuration(), this.srvLsnr, getName(), getWorkersRegistry(ignite), ignite instanceof IgniteEx ? ((IgniteEx) ignite).context().metric() : null, this::createTcpClient, new CommunicationListenerEx<Message>() {
@Override
public void onMessage(UUID nodeId, Message msg, IgniteRunnable msgC) {
notifyListener(nodeId, msg, msgC);
}
@Override
public void onDisconnected(UUID nodeId) {
if (lsnr != null)
lsnr.onDisconnected(nodeId);
}
@Override
public void onChannelOpened(UUID rmtNodeId, Message initMsg, Channel channel) {
if (lsnr instanceof CommunicationListenerEx)
((CommunicationListenerEx<Message>) lsnr).onChannelOpened(rmtNodeId, initMsg, channel);
}
}, tcpHandshakeExecutor));
this.srvLsnr.setNioSrvWrapper(nioSrvWrapper);
this.clientPool = resolve(ignite, new ConnectionClientPool(cfg, attributeNames, log, metricsLsnr, locNodeSupplier, nodeGetter, null, getWorkersRegistry(ignite), this, stateProvider, nioSrvWrapper, getName()));
this.srvLsnr.setClientPool(clientPool);
nioSrvWrapper.clientPool(clientPool);
discoLsnr = new CommunicationDiscoveryEventListener(clientPool, metricsLsnr);
try {
// This method potentially resets local port to the value
// local node was bound to.
nioSrvWrapper.nio(nioSrvWrapper.resetNioServer());
} catch (IgniteCheckedException e) {
throw new IgniteSpiException("Failed to initialize TCP server: " + cfg.localHost(), e);
}
boolean forceClientToSrvConnections = forceClientToServerConnections() || cfg.localPort() == -1;
if (cfg.usePairedConnections() && forceClientToSrvConnections) {
throw new IgniteSpiException("Node using paired connections " + "is not allowed to start in forced client to server connections mode.");
}
assert cfg.localHost() != null;
// Start SPI start stopwatch.
startStopwatch();
if (log.isDebugEnabled()) {
log.debug(configInfo("locAddr", cfg.localAddress()));
log.debug(configInfo("locPort", cfg.localPort()));
log.debug(configInfo("locPortRange", cfg.localPortRange()));
log.debug(configInfo("idleConnTimeout", cfg.idleConnectionTimeout()));
log.debug(configInfo("directBuf", cfg.directBuffer()));
log.debug(configInfo("directSendBuf", cfg.directSendBuffer()));
log.debug(configInfo("selectorsCnt", cfg.selectorsCount()));
log.debug(configInfo("tcpNoDelay", cfg.tcpNoDelay()));
log.debug(configInfo("sockSndBuf", cfg.socketSendBuffer()));
log.debug(configInfo("sockRcvBuf", cfg.socketReceiveBuffer()));
log.debug(configInfo("msgQueueLimit", cfg.messageQueueLimit()));
log.debug(configInfo("connectionsPerNode", cfg.connectionsPerNode()));
if (failureDetectionTimeoutEnabled()) {
log.debug(configInfo("connTimeout", cfg.connectionTimeout()));
log.debug(configInfo("maxConnTimeout", cfg.maxConnectionTimeout()));
log.debug(configInfo("reconCnt", cfg.reconCount()));
} else
log.debug(configInfo("failureDetectionTimeout", failureDetectionTimeout()));
log.debug(configInfo("sockWriteTimeout", cfg.socketWriteTimeout()));
log.debug(configInfo("ackSndThreshold", cfg.ackSendThreshold()));
log.debug(configInfo("unackedMsgsBufSize", cfg.unackedMsgsBufferSize()));
}
if (!cfg.tcpNoDelay())
U.quietAndWarn(log, "'TCP_NO_DELAY' for communication is off, which should be used with caution " + "since may produce significant delays with some scenarios.");
if (cfg.slowClientQueueLimit() > 0 && cfg.messageQueueLimit() > 0 && cfg.slowClientQueueLimit() >= cfg.messageQueueLimit()) {
U.quietAndWarn(log, "Slow client queue limit is set to a value greater than or equal to message " + "queue limit (slow client queue limit will have no effect) [msgQueueLimit=" + cfg.messageQueueLimit() + ", slowClientQueueLimit=" + cfg.slowClientQueueLimit() + ']');
}
if (cfg.messageQueueLimit() == 0)
U.quietAndWarn(log, "Message queue limit is set to 0 which may lead to " + "potential OOMEs when running cache operations in FULL_ASYNC or PRIMARY_SYNC modes " + "due to message queues growth on sender and receiver sides.");
nioSrvWrapper.start();
this.commWorker = new CommunicationWorker(igniteInstanceName, log, cfg, attributeNames, clientPool, failureProcessorSupplier, nodeGetter, pingNode, this::getExceptionRegistry, nioSrvWrapper, getWorkersRegistry(ignite), getName());
this.srvLsnr.communicationWorker(commWorker);
this.nioSrvWrapper.communicationWorker(commWorker);
new IgniteSpiThread(igniteInstanceName, commWorker.name(), log) {
@Override
protected void body() {
commWorker.run();
}
}.start();
// Ack start.
if (log.isDebugEnabled())
log.debug(startInfo());
}
use of org.apache.ignite.spi.communication.CommunicationListener in project ignite by apache.
the class GridIoManager method start.
/** {@inheritDoc} */
@SuppressWarnings("deprecation")
@Override
public void start(boolean activeOnStart) throws IgniteCheckedException {
assertParameter(discoDelay > 0, "discoveryStartupDelay > 0");
startSpi();
getSpi().setListener(commLsnr = new CommunicationListener<Serializable>() {
@Override
public void onMessage(UUID nodeId, Serializable msg, IgniteRunnable msgC) {
try {
onMessage0(nodeId, (GridIoMessage) msg, msgC);
} catch (ClassCastException ignored) {
U.error(log, "Communication manager received message of unknown type (will ignore): " + msg.getClass().getName() + ". Most likely GridCommunicationSpi is being used directly, " + "which is illegal - make sure to send messages only via GridProjection API.");
}
}
@Override
public void onDisconnected(UUID nodeId) {
for (GridDisconnectListener lsnr : disconnectLsnrs) lsnr.onNodeDisconnected(nodeId);
}
});
ctx.addNodeAttribute(DIRECT_PROTO_VER_ATTR, DIRECT_PROTO_VER);
MessageFormatter[] formatterExt = ctx.plugins().extensions(MessageFormatter.class);
if (formatterExt != null && formatterExt.length > 0) {
if (formatterExt.length > 1)
throw new IgniteCheckedException("More than one MessageFormatter extension is defined. Check your " + "plugins configuration and make sure that only one of them provides custom message format.");
formatter = formatterExt[0];
} else {
formatter = new MessageFormatter() {
@Override
public MessageWriter writer(UUID rmtNodeId) throws IgniteCheckedException {
assert rmtNodeId != null;
return new DirectMessageWriter(U.directProtocolVersion(ctx, rmtNodeId));
}
@Override
public MessageReader reader(UUID rmtNodeId, MessageFactory msgFactory) throws IgniteCheckedException {
assert rmtNodeId != null;
return new DirectMessageReader(msgFactory, U.directProtocolVersion(ctx, rmtNodeId));
}
};
}
MessageFactory[] msgs = ctx.plugins().extensions(MessageFactory.class);
if (msgs == null)
msgs = EMPTY;
List<MessageFactory> compMsgs = new ArrayList<>();
for (IgniteComponentType compType : IgniteComponentType.values()) {
MessageFactory f = compType.messageFactory();
if (f != null)
compMsgs.add(f);
}
if (!compMsgs.isEmpty())
msgs = F.concat(msgs, compMsgs.toArray(new MessageFactory[compMsgs.size()]));
msgFactory = new GridIoMessageFactory(msgs);
if (log.isDebugEnabled())
log.debug(startInfo());
addMessageListener(GridTopic.TOPIC_IO_TEST, new GridMessageListener() {
@Override
public void onMessage(UUID nodeId, Object msg) {
ClusterNode node = ctx.discovery().node(nodeId);
if (node == null)
return;
IgniteIoTestMessage msg0 = (IgniteIoTestMessage) msg;
msg0.senderNodeId(nodeId);
if (msg0.request()) {
IgniteIoTestMessage res = new IgniteIoTestMessage(msg0.id(), false, null);
res.flags(msg0.flags());
res.onRequestProcessed();
res.copyDataFromRequest(msg0);
try {
sendToGridTopic(node, GridTopic.TOPIC_IO_TEST, res, GridIoPolicy.SYSTEM_POOL);
} catch (IgniteCheckedException e) {
U.error(log, "Failed to send IO test response [msg=" + msg0 + "]", e);
}
} else {
IoTestFuture fut = ioTestMap().get(msg0.id());
msg0.onResponseProcessed();
if (fut == null)
U.warn(log, "Failed to find IO test future [msg=" + msg0 + ']');
else
fut.onResponse(msg0);
}
}
});
}
Aggregations