use of org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeLeftMessage in project ignite by apache.
the class ServerImpl method spiStop0.
/**
* Stops SPI finally or stops SPI for restart.
*
* @param disconnect {@code True} if SPI is being disconnected.
* @throws IgniteSpiException If failed.
*/
private void spiStop0(boolean disconnect) throws IgniteSpiException {
if (log.isDebugEnabled()) {
if (disconnect)
log.debug("Disconnecting SPI.");
else
log.debug("Preparing to start local node stop procedure.");
}
if (disconnect) {
synchronized (mux) {
spiState = DISCONNECTING;
}
}
if (msgWorker != null && msgWorker.runner() != null && msgWorker.runner().isAlive() && !disconnect) {
// Send node left message only if it is final stop.
TcpDiscoveryNodeLeftMessage nodeLeftMsg = new TcpDiscoveryNodeLeftMessage(locNode.id());
Span rootSpan = tracing.create(TraceableMessagesTable.traceName(nodeLeftMsg.getClass())).addTag(SpanTags.tag(SpanTags.EVENT_NODE, SpanTags.ID), () -> locNode.id().toString()).addTag(SpanTags.tag(SpanTags.EVENT_NODE, SpanTags.CONSISTENT_ID), () -> locNode.consistentId().toString()).addLog(() -> "Created");
nodeLeftMsg.spanContainer().serializedSpanBytes(tracing.serialize(rootSpan));
msgWorker.addMessage(nodeLeftMsg);
rootSpan.addLog(() -> "Sent").end();
synchronized (mux) {
long timeout = spi.netTimeout;
long thresholdNanos = System.nanoTime() + U.millisToNanos(timeout);
while (spiState != LEFT && timeout > 0) {
try {
mux.wait(timeout);
timeout = U.nanosToMillis(thresholdNanos - System.nanoTime());
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
break;
}
}
if (spiState == LEFT) {
if (log.isDebugEnabled())
log.debug("Verification for local node leave has been received from coordinator" + " (continuing stop procedure).");
} else if (log.isInfoEnabled()) {
log.info("No verification for local node leave has been received from coordinator" + " (will stop node anyway).");
}
}
}
if (tcpSrvr != null)
tcpSrvr.stop();
tcpSrvr = null;
Collection<SocketReader> tmp;
synchronized (mux) {
tmp = U.arrayList(readers);
}
U.interrupt(tmp);
U.joinThreads(tmp, log);
U.interrupt(ipFinderCleaner);
U.join(ipFinderCleaner, log);
U.cancel(msgWorker);
U.join(msgWorker, log);
for (ClientMessageWorker clientWorker : clientMsgWorkers.values()) {
if (clientWorker != null) {
U.interrupt(clientWorker.runner());
U.join(clientWorker.runner(), log);
}
}
clientMsgWorkers.clear();
IgniteUtils.shutdownNow(ServerImpl.class, utilityPool, log);
U.interrupt(statsPrinter);
U.join(statsPrinter, log);
Collection<TcpDiscoveryNode> nodes = null;
if (!disconnect)
spi.printStopInfo();
else {
spi.getSpiContext().deregisterPorts();
nodes = ring.visibleNodes();
}
long topVer = ring.topologyVersion();
ring.clear();
if (nodes != null) {
// This is restart/disconnection and we need to fire FAIL event for each remote node.
DiscoverySpiListener lsnr = spi.lsnr;
if (lsnr != null) {
Collection<ClusterNode> processed = new HashSet<>(nodes.size());
for (TcpDiscoveryNode n : nodes) {
if (n.isLocal())
continue;
assert n.visible();
processed.add(n);
List<ClusterNode> top = U.arrayList(nodes, F.notIn(processed));
topVer++;
Map<Long, Collection<ClusterNode>> hist = updateTopologyHistory(topVer, Collections.unmodifiableList(top));
lsnr.onDiscovery(new DiscoveryNotification(EVT_NODE_FAILED, topVer, n, top, hist, null, null)).get();
}
}
}
printStatistics();
spi.stats.clear();
synchronized (mux) {
// Clear stored data.
leavingNodes.clear();
failedNodes.clear();
spiState = DISCONNECTED;
}
}
use of org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeLeftMessage in project ignite by apache.
the class TcpDiscoverySelfTest method testFailBeforeNodeLeftSent.
/**
* @throws Exception If any error occurs.
*/
@Test
public void testFailBeforeNodeLeftSent() throws Exception {
try {
startGrid(1);
startGrid(2);
final Ignite g = startGrid("FailBeforeNodeLeftSentSpi");
discoMap.get(g.name()).addSendMessageListener(new IgniteInClosure<TcpDiscoveryAbstractMessage>() {
@Override
public void apply(TcpDiscoveryAbstractMessage msg) {
if (msg instanceof TcpDiscoveryNodeLeftMessage) {
discoMap.get(g.name()).simulateNodeFailure();
throw new RuntimeException("Avoid message sending: " + msg.getClass());
}
}
});
Ignite g3 = startGrid(3);
final CountDownLatch cnt = new CountDownLatch(1);
g3.events().localListen(new IgnitePredicate<Event>() {
@Override
public boolean apply(Event evt) {
cnt.countDown();
return true;
}
}, EVT_NODE_FAILED);
stopGrid(1);
assert cnt.await(20, SECONDS);
} finally {
stopAllGrids();
}
}
Aggregations