use of org.apache.ignite.events.DiscoveryEvent in project ignite by apache.
the class IgniteSlowClientDetectionSelfTest method testSlowClient.
/**
* @throws Exception If failed.
*/
public void testSlowClient() throws Exception {
final IgniteEx slowClient = grid(nodeCount() - 1);
final ClusterNode slowClientNode = slowClient.localNode();
final CountDownLatch evtSegmentedLatch = new CountDownLatch(1);
slowClient.events().localListen(new IgnitePredicate<Event>() {
@Override
public boolean apply(Event evt) {
assertEquals("Unexpected event: " + evt, evt.type(), EventType.EVT_NODE_SEGMENTED);
DiscoveryEvent evt0 = (DiscoveryEvent) evt;
assertEquals(slowClientNode, evt0.eventNode());
assertEquals(5L, evt0.topologyVersion());
evtSegmentedLatch.countDown();
return false;
}
}, EventType.EVT_NODE_SEGMENTED);
final CountDownLatch evtFailedLatch = new CountDownLatch(nodeCount() - 1);
for (int i = 0; i < nodeCount() - 1; i++) {
grid(i).events().localListen(new IgnitePredicate<Event>() {
@Override
public boolean apply(Event evt) {
assertEquals("Unexpected event: " + evt, evt.type(), EventType.EVT_NODE_FAILED);
DiscoveryEvent evt0 = (DiscoveryEvent) evt;
assertEquals(slowClientNode, evt0.eventNode());
assertEquals(6L, evt0.topologyVersion());
assertEquals(4, evt0.topologyNodes().size());
evtFailedLatch.countDown();
return false;
}
}, EventType.EVT_NODE_FAILED);
}
assertTrue(slowClient.cluster().localNode().isClient());
IgniteCache<Object, Object> cache = slowClient.getOrCreateCache(PARTITIONED);
IgniteEx client0 = grid(nodeCount() - 2);
assertTrue(client0.cluster().localNode().isClient());
IgniteCache<Object, Object> cache0 = client0.getOrCreateCache(PARTITIONED);
cache.query(new ContinuousQuery<>().setLocalListener(new Listener()));
for (int i = 0; i < 100; i++) cache0.put(0, i);
GridIoManager ioMgr = slowClient.context().io();
TcpCommunicationSpi commSpi = (TcpCommunicationSpi) ((Object[]) U.field(ioMgr, "spis"))[0];
GridNioServer nioSrvr = U.field(commSpi, "nioSrvr");
GridTestUtils.setFieldValue(nioSrvr, "skipRead", true);
// Initiate messages for client.
for (int i = 0; i < 100; i++) cache0.put(0, new byte[10 * 1024]);
boolean wait = GridTestUtils.waitForCondition(new GridAbsPredicate() {
@Override
public boolean apply() {
return Ignition.state(slowClient.name()) == IgniteState.STOPPED_ON_SEGMENTATION;
}
}, getTestTimeout());
assertTrue(wait);
assertTrue("Failed to wait for client failed event", evtFailedLatch.await(5000, MILLISECONDS));
assertTrue("Failed to wait for client segmented event", evtSegmentedLatch.await(5000, MILLISECONDS));
}
use of org.apache.ignite.events.DiscoveryEvent in project ignite by apache.
the class GridDiscoveryManager method start.
/** {@inheritDoc} */
@Override
public void start(boolean activeOnStart) throws IgniteCheckedException {
long totSysMemory = -1;
try {
totSysMemory = U.<Long>property(os, "totalPhysicalMemorySize");
} catch (RuntimeException ignored) {
// No-op.
}
ctx.addNodeAttribute(IgniteNodeAttributes.ATTR_PHY_RAM, totSysMemory);
DiscoverySpi spi = getSpi();
discoOrdered = discoOrdered();
histSupported = historySupported();
isLocDaemon = ctx.isDaemon();
hasRslvrs = !ctx.config().isClientMode() && !F.isEmpty(ctx.config().getSegmentationResolvers());
segChkFreq = ctx.config().getSegmentCheckFrequency();
if (hasRslvrs) {
if (segChkFreq < 0)
throw new IgniteCheckedException("Segment check frequency cannot be negative: " + segChkFreq);
if (segChkFreq > 0 && segChkFreq < 2000)
U.warn(log, "Configuration parameter 'segmentCheckFrequency' is too low " + "(at least 2000 ms recommended): " + segChkFreq);
int segResAttemp = ctx.config().getSegmentationResolveAttempts();
if (segResAttemp < 1)
throw new IgniteCheckedException("Segment resolve attempts cannot be negative or zero: " + segResAttemp);
checkSegmentOnStart();
}
metricsUpdateTask = ctx.timeout().schedule(new MetricsUpdater(), METRICS_UPDATE_FREQ, METRICS_UPDATE_FREQ);
spi.setMetricsProvider(createMetricsProvider());
if (ctx.security().enabled()) {
if (isSecurityCompatibilityMode())
ctx.addNodeAttribute(ATTR_SECURITY_COMPATIBILITY_MODE, true);
spi.setAuthenticator(new DiscoverySpiNodeAuthenticator() {
@Override
public SecurityContext authenticateNode(ClusterNode node, SecurityCredentials cred) {
try {
return ctx.security().authenticateNode(node, cred);
} catch (IgniteCheckedException e) {
throw U.convertException(e);
}
}
@Override
public boolean isGlobalNodeAuthentication() {
return ctx.security().isGlobalNodeAuthentication();
}
});
}
spi.setListener(new DiscoverySpiListener() {
private long gridStartTime;
/** {@inheritDoc} */
@Override
public void onLocalNodeInitialized(ClusterNode locNode) {
for (IgniteInClosure<ClusterNode> lsnr : localNodeInitLsnrs) lsnr.apply(locNode);
}
@Override
public void onDiscovery(final int type, final long topVer, final ClusterNode node, final Collection<ClusterNode> topSnapshot, final Map<Long, Collection<ClusterNode>> snapshots, @Nullable DiscoverySpiCustomMessage spiCustomMsg) {
DiscoveryCustomMessage customMsg = spiCustomMsg == null ? null : ((CustomMessageWrapper) spiCustomMsg).delegate();
if (skipMessage(type, customMsg))
return;
final ClusterNode locNode = localNode();
if (snapshots != null)
topHist = snapshots;
boolean verChanged;
if (type == EVT_NODE_METRICS_UPDATED)
verChanged = false;
else {
if (type != EVT_NODE_SEGMENTED && type != EVT_CLIENT_NODE_DISCONNECTED && type != EVT_CLIENT_NODE_RECONNECTED && type != DiscoveryCustomEvent.EVT_DISCOVERY_CUSTOM_EVT) {
minorTopVer = 0;
verChanged = true;
} else
verChanged = false;
}
if (type == EVT_NODE_FAILED || type == EVT_NODE_LEFT) {
for (DiscoCache c : discoCacheHist.values()) c.updateAlives(node);
updateClientNodes(node.id());
}
final AffinityTopologyVersion nextTopVer;
if (type == DiscoveryCustomEvent.EVT_DISCOVERY_CUSTOM_EVT) {
assert customMsg != null;
boolean incMinorTopVer = ctx.cache().onCustomEvent(customMsg, new AffinityTopologyVersion(topVer, minorTopVer));
if (incMinorTopVer) {
minorTopVer++;
verChanged = true;
}
nextTopVer = new AffinityTopologyVersion(topVer, minorTopVer);
if (verChanged)
ctx.cache().onDiscoveryEvent(type, node, nextTopVer);
} else {
nextTopVer = new AffinityTopologyVersion(topVer, minorTopVer);
ctx.cache().onDiscoveryEvent(type, node, nextTopVer);
}
if (type == DiscoveryCustomEvent.EVT_DISCOVERY_CUSTOM_EVT) {
for (Class cls = customMsg.getClass(); cls != null; cls = cls.getSuperclass()) {
List<CustomEventListener<DiscoveryCustomMessage>> list = customEvtLsnrs.get(cls);
if (list != null) {
for (CustomEventListener<DiscoveryCustomMessage> lsnr : list) {
try {
lsnr.onCustomEvent(nextTopVer, node, customMsg);
} catch (Exception e) {
U.error(log, "Failed to notify direct custom event listener: " + customMsg, e);
}
}
}
}
}
final DiscoCache discoCache;
// event notifications, since SPI notifies manager about all events from this listener.
if (verChanged) {
discoCache = createDiscoCache(locNode, topSnapshot);
discoCacheHist.put(nextTopVer, discoCache);
boolean set = updateTopologyVersionIfGreater(nextTopVer, discoCache);
assert set || topVer == 0 : "Topology version has not been updated [this.topVer=" + topSnap + ", topVer=" + topVer + ", node=" + node + ", evt=" + U.gridEventName(type) + ']';
} else
// Current version.
discoCache = discoCache();
// If this is a local join event, just save it and do not notify listeners.
if (type == EVT_NODE_JOINED && node.id().equals(locNode.id())) {
if (gridStartTime == 0)
gridStartTime = getSpi().getGridStartTime();
updateTopologyVersionIfGreater(new AffinityTopologyVersion(locNode.order()), discoCache);
startLatch.countDown();
DiscoveryEvent discoEvt = new DiscoveryEvent();
discoEvt.node(ctx.discovery().localNode());
discoEvt.eventNode(node);
discoEvt.type(EVT_NODE_JOINED);
discoEvt.topologySnapshot(topVer, new ArrayList<>(F.view(topSnapshot, FILTER_DAEMON)));
locJoin.onDone(new T2<>(discoEvt, discoCache));
return;
} else if (type == EVT_CLIENT_NODE_DISCONNECTED) {
assert locNode.isClient() : locNode;
assert node.isClient() : node;
((IgniteKernal) ctx.grid()).onDisconnected();
locJoin = new GridFutureAdapter<>();
registeredCaches.clear();
for (AffinityTopologyVersion histVer : discoCacheHist.keySet()) {
Object rmvd = discoCacheHist.remove(histVer);
assert rmvd != null : histVer;
}
topHist.clear();
topSnap.set(new Snapshot(AffinityTopologyVersion.ZERO, createDiscoCache(locNode, Collections.<ClusterNode>emptySet())));
} else if (type == EVT_CLIENT_NODE_RECONNECTED) {
assert locNode.isClient() : locNode;
assert node.isClient() : node;
boolean clusterRestarted = gridStartTime != getSpi().getGridStartTime();
gridStartTime = getSpi().getGridStartTime();
((IgniteKernal) ctx.grid()).onReconnected(clusterRestarted);
ctx.cluster().clientReconnectFuture().listen(new CI1<IgniteFuture<?>>() {
@Override
public void apply(IgniteFuture<?> fut) {
try {
fut.get();
discoWrk.addEvent(type, nextTopVer, node, discoCache, topSnapshot, null);
} catch (IgniteException ignore) {
// No-op.
}
}
});
return;
}
if (type == EVT_CLIENT_NODE_DISCONNECTED || type == EVT_NODE_SEGMENTED || !ctx.clientDisconnected())
discoWrk.addEvent(type, nextTopVer, node, discoCache, topSnapshot, customMsg);
}
});
spi.setDataExchange(new DiscoverySpiDataExchange() {
@Override
public DiscoveryDataBag collect(DiscoveryDataBag dataBag) {
assert dataBag != null;
assert dataBag.joiningNodeId() != null;
if (ctx.localNodeId().equals(dataBag.joiningNodeId())) {
for (GridComponent c : ctx.components()) c.collectJoiningNodeData(dataBag);
} else {
for (GridComponent c : ctx.components()) c.collectGridNodeData(dataBag);
}
return dataBag;
}
@Override
public void onExchange(DiscoveryDataBag dataBag) {
if (ctx.localNodeId().equals(dataBag.joiningNodeId())) {
//NodeAdded msg reached joining node after round-trip over the ring
for (GridComponent c : ctx.components()) {
if (c.discoveryDataType() != null)
c.onGridDataReceived(dataBag.gridDiscoveryData(c.discoveryDataType().ordinal()));
}
} else {
//discovery data from newly joined node has to be applied to the current old node
for (GridComponent c : ctx.components()) {
if (c.discoveryDataType() != null) {
JoiningNodeDiscoveryData data = dataBag.newJoinerDiscoveryData(c.discoveryDataType().ordinal());
if (data != null)
c.onJoiningNodeDataReceived(data);
}
}
}
}
});
startSpi();
registeredDiscoSpi = true;
try {
U.await(startLatch);
} catch (IgniteInterruptedException e) {
throw new IgniteCheckedException("Failed to start discovery manager (thread has been interrupted).", e);
}
// Start segment check worker only if frequency is greater than 0.
if (hasRslvrs && segChkFreq > 0) {
segChkWrk = new SegmentCheckWorker();
segChkThread = new IgniteThread(segChkWrk);
segChkThread.start();
}
locNode = spi.getLocalNode();
checkAttributes(discoCache().remoteNodes());
ctx.service().initCompatibilityMode(discoCache().remoteNodes());
// Start discovery worker.
new IgniteThread(discoWrk).start();
if (log.isDebugEnabled())
log.debug(startInfo());
}
use of org.apache.ignite.events.DiscoveryEvent in project ignite by apache.
the class GridEventStorageManager method query.
/**
* @param p Grid event predicate.
* @param nodes Collection of nodes.
* @param timeout Maximum time to wait for result, if {@code 0}, then wait until result is received.
* @return Collection of events.
* @throws IgniteCheckedException Thrown in case of any errors.
*/
@SuppressWarnings({ "SynchronizationOnLocalVariableOrMethodParameter", "deprecation" })
private <T extends Event> List<T> query(IgnitePredicate<T> p, Collection<? extends ClusterNode> nodes, long timeout) throws IgniteCheckedException {
assert p != null;
assert nodes != null;
if (nodes.isEmpty()) {
U.warn(log, "Failed to query events for empty nodes collection.");
return Collections.emptyList();
}
GridIoManager ioMgr = ctx.io();
final List<T> evts = new ArrayList<>();
final AtomicReference<Throwable> err = new AtomicReference<>();
final Set<UUID> uids = new HashSet<>();
final Object qryMux = new Object();
for (ClusterNode node : nodes) uids.add(node.id());
GridLocalEventListener evtLsnr = new GridLocalEventListener() {
@Override
public void onEvent(Event evt) {
assert evt instanceof DiscoveryEvent;
synchronized (qryMux) {
uids.remove(((DiscoveryEvent) evt).eventNode().id());
if (uids.isEmpty())
qryMux.notifyAll();
}
}
};
GridMessageListener resLsnr = new GridMessageListener() {
@SuppressWarnings("deprecation")
@Override
public void onMessage(UUID nodeId, Object msg) {
assert nodeId != null;
assert msg != null;
if (!(msg instanceof GridEventStorageMessage)) {
U.error(log, "Received unknown message: " + msg);
return;
}
GridEventStorageMessage res = (GridEventStorageMessage) msg;
try {
if (res.eventsBytes() != null)
res.events(U.<Collection<Event>>unmarshal(marsh, res.eventsBytes(), U.resolveClassLoader(ctx.config())));
if (res.exceptionBytes() != null)
res.exception(U.<Throwable>unmarshal(marsh, res.exceptionBytes(), U.resolveClassLoader(ctx.config())));
} catch (IgniteCheckedException e) {
U.error(log, "Failed to unmarshal events query response: " + msg, e);
return;
}
synchronized (qryMux) {
if (uids.remove(nodeId)) {
if (res.events() != null)
evts.addAll((Collection<T>) res.events());
} else
U.warn(log, "Received duplicate response (ignoring) [nodeId=" + nodeId + ", msg=" + res + ']');
if (res.exception() != null)
err.set(res.exception());
if (uids.isEmpty() || err.get() != null)
qryMux.notifyAll();
}
}
};
Object resTopic = TOPIC_EVENT.topic(IgniteUuid.fromUuid(ctx.localNodeId()));
try {
addLocalEventListener(evtLsnr, new int[] { EVT_NODE_LEFT, EVT_NODE_FAILED });
ioMgr.addMessageListener(resTopic, resLsnr);
byte[] serFilter = U.marshal(marsh, p);
GridDeployment dep = ctx.deploy().deploy(p.getClass(), U.detectClassLoader(p.getClass()));
if (dep == null)
throw new IgniteDeploymentCheckedException("Failed to deploy event filter: " + p);
GridEventStorageMessage msg = new GridEventStorageMessage(resTopic, serFilter, p.getClass().getName(), dep.classLoaderId(), dep.deployMode(), dep.userVersion(), dep.participants());
sendMessage(nodes, TOPIC_EVENT, msg, PUBLIC_POOL);
if (timeout == 0)
timeout = Long.MAX_VALUE;
long now = U.currentTimeMillis();
// Account for overflow of long value.
long endTime = now + timeout <= 0 ? Long.MAX_VALUE : now + timeout;
long delta = timeout;
Collection<UUID> uidsCp = null;
synchronized (qryMux) {
try {
while (!uids.isEmpty() && err.get() == null && delta > 0) {
qryMux.wait(delta);
delta = endTime - U.currentTimeMillis();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IgniteCheckedException("Got interrupted while waiting for event query responses.", e);
}
if (err.get() != null)
throw new IgniteCheckedException("Failed to query events due to exception on remote node.", err.get());
if (!uids.isEmpty())
uidsCp = new LinkedList<>(uids);
}
// Outside of synchronization.
if (uidsCp != null) {
for (Iterator<UUID> iter = uidsCp.iterator(); iter.hasNext(); ) // Ignore nodes that have left the grid.
if (ctx.discovery().node(iter.next()) == null)
iter.remove();
if (!uidsCp.isEmpty())
throw new IgniteCheckedException("Failed to receive event query response from following nodes: " + uidsCp);
}
} finally {
ioMgr.removeMessageListener(resTopic, resLsnr);
removeLocalEventListener(evtLsnr);
}
return evts;
}
use of org.apache.ignite.events.DiscoveryEvent in project ignite by apache.
the class GridIoManager method onKernalStart0.
/** {@inheritDoc} */
@SuppressWarnings({ "deprecation", "SynchronizationOnLocalVariableOrMethodParameter" })
@Override
public void onKernalStart0() throws IgniteCheckedException {
discoLsnr = new GridLocalEventListener() {
@SuppressWarnings({ "TooBroadScope", "fallthrough" })
@Override
public void onEvent(Event evt) {
assert evt instanceof DiscoveryEvent : "Invalid event: " + evt;
DiscoveryEvent discoEvt = (DiscoveryEvent) evt;
UUID nodeId = discoEvt.eventNode().id();
switch(evt.type()) {
case EVT_NODE_JOINED:
// We can't receive messages from undiscovered nodes.
assert waitMap.get(nodeId) == null;
break;
case EVT_NODE_LEFT:
case EVT_NODE_FAILED:
for (Map.Entry<Object, ConcurrentMap<UUID, GridCommunicationMessageSet>> e : msgSetMap.entrySet()) {
ConcurrentMap<UUID, GridCommunicationMessageSet> map = e.getValue();
GridCommunicationMessageSet set;
boolean empty;
synchronized (map) {
set = map.remove(nodeId);
empty = map.isEmpty();
}
if (set != null) {
if (log.isDebugEnabled())
log.debug("Removed message set due to node leaving grid: " + set);
// Unregister timeout listener.
ctx.timeout().removeTimeoutObject(set);
// Node may still send stale messages for this topic
// even after discovery notification is done.
closedTopics.add(set.topic());
}
if (empty)
msgSetMap.remove(e.getKey(), map);
}
// Clean up delayed and ordered messages (need exclusive lock).
lock.writeLock().lock();
try {
ConcurrentLinkedDeque8<DelayedMessage> waitList = waitMap.remove(nodeId);
if (log.isDebugEnabled())
log.debug("Removed messages from discovery startup delay list " + "(sender node left topology): " + waitList);
} finally {
lock.writeLock().unlock();
}
break;
default:
assert false : "Unexpected event: " + evt;
}
}
};
ctx.event().addLocalEventListener(discoLsnr, EVT_NODE_JOINED, EVT_NODE_LEFT, EVT_NODE_FAILED);
// Make sure that there are no stale messages due to window between communication
// manager start and kernal start.
// 1. Process wait list.
Collection<Collection<DelayedMessage>> delayedMsgs = new ArrayList<>();
lock.writeLock().lock();
try {
started = true;
for (Entry<UUID, ConcurrentLinkedDeque8<DelayedMessage>> e : waitMap.entrySet()) {
if (ctx.discovery().node(e.getKey()) != null) {
ConcurrentLinkedDeque8<DelayedMessage> waitList = waitMap.remove(e.getKey());
if (log.isDebugEnabled())
log.debug("Processing messages from discovery startup delay list: " + waitList);
if (waitList != null)
delayedMsgs.add(waitList);
}
}
} finally {
lock.writeLock().unlock();
}
// After write lock released.
if (!delayedMsgs.isEmpty()) {
for (Collection<DelayedMessage> col : delayedMsgs) for (DelayedMessage msg : col) commLsnr.onMessage(msg.nodeId(), msg.message(), msg.callback());
}
// 2. Process messages sets.
for (Map.Entry<Object, ConcurrentMap<UUID, GridCommunicationMessageSet>> e : msgSetMap.entrySet()) {
ConcurrentMap<UUID, GridCommunicationMessageSet> map = e.getValue();
for (GridCommunicationMessageSet set : map.values()) {
if (ctx.discovery().node(set.nodeId()) == null) {
// All map modifications should be synced for consistency.
boolean rmv;
synchronized (map) {
rmv = map.remove(set.nodeId(), set);
}
if (rmv) {
if (log.isDebugEnabled())
log.debug("Removed message set due to node leaving grid: " + set);
// Unregister timeout listener.
ctx.timeout().removeTimeoutObject(set);
}
}
}
boolean rmv;
synchronized (map) {
rmv = map.isEmpty();
}
if (rmv) {
msgSetMap.remove(e.getKey(), map);
// Node may still send stale messages for this topic
// even after discovery notification is done.
closedTopics.add(e.getKey());
}
}
}
use of org.apache.ignite.events.DiscoveryEvent in project ignite by apache.
the class GridDeploymentCommunication method sendResourceRequest.
/**
* Sends request to the remote node and wait for response. If there is
* no response until threshold time, method returns null.
*
*
* @param rsrcName Resource name.
* @param clsLdrId Class loader ID.
* @param dstNode Remote node request should be sent to.
* @param threshold Time in milliseconds when request is decided to
* be obsolete.
* @return Either response value or {@code null} if timeout occurred.
* @throws IgniteCheckedException Thrown if there is no connection with remote node.
*/
@SuppressWarnings({ "SynchronizationOnLocalVariableOrMethodParameter" })
GridDeploymentResponse sendResourceRequest(final String rsrcName, IgniteUuid clsLdrId, final ClusterNode dstNode, long threshold) throws IgniteCheckedException {
assert rsrcName != null;
assert dstNode != null;
assert clsLdrId != null;
Collection<UUID> nodeIds = activeReqNodeIds.get();
if (nodeIds != null && nodeIds.contains(dstNode.id())) {
if (log.isDebugEnabled())
log.debug("Node attempts to load resource from one of the requesters " + "[rsrcName=" + rsrcName + ", dstNodeId=" + dstNode.id() + ", requesters=" + nodeIds + ']');
GridDeploymentResponse fake = new GridDeploymentResponse();
fake.success(false);
fake.errorMessage("Node attempts to load resource from one of the requesters " + "[rsrcName=" + rsrcName + ", dstNodeId=" + dstNode.id() + ", requesters=" + nodeIds + ']');
return fake;
}
Object resTopic = TOPIC_CLASSLOAD.topic(IgniteUuid.fromUuid(ctx.localNodeId()));
GridDeploymentRequest req = new GridDeploymentRequest(resTopic, clsLdrId, rsrcName, false);
// Send node IDs chain with request.
req.nodeIds(nodeIds);
final Object qryMux = new Object();
final GridTuple<GridDeploymentResponse> res = new GridTuple<>();
GridLocalEventListener discoLsnr = new GridLocalEventListener() {
@Override
public void onEvent(Event evt) {
assert evt instanceof DiscoveryEvent;
assert evt.type() == EVT_NODE_LEFT || evt.type() == EVT_NODE_FAILED;
DiscoveryEvent discoEvt = (DiscoveryEvent) evt;
UUID nodeId = discoEvt.eventNode().id();
if (!nodeId.equals(dstNode.id()))
// Not a destination node.
return;
GridDeploymentResponse fake = new GridDeploymentResponse();
String errMsg = "Originating node left grid (resource will not be peer loaded) " + "[nodeId=" + dstNode.id() + ", rsrc=" + rsrcName + ']';
U.warn(log, errMsg);
fake.success(false);
fake.errorMessage(errMsg);
// because originating node has left grid.
synchronized (qryMux) {
res.set(fake);
qryMux.notifyAll();
}
}
};
GridMessageListener resLsnr = new GridMessageListener() {
@Override
public void onMessage(UUID nodeId, Object msg) {
assert nodeId != null;
assert msg != null;
synchronized (qryMux) {
if (!(msg instanceof GridDeploymentResponse)) {
U.error(log, "Received unknown peer class loading response [node=" + nodeId + ", msg=" + msg + ']');
} else
res.set((GridDeploymentResponse) msg);
qryMux.notifyAll();
}
}
};
try {
ctx.io().addMessageListener(resTopic, resLsnr);
// The destination node has potentially left grid here but in this case
// Communication manager will throw the exception while sending message.
ctx.event().addLocalEventListener(discoLsnr, EVT_NODE_FAILED, EVT_NODE_LEFT);
long start = U.currentTimeMillis();
if (req.responseTopic() != null && !ctx.localNodeId().equals(dstNode.id()))
req.responseTopicBytes(U.marshal(marsh, req.responseTopic()));
ctx.io().sendToGridTopic(dstNode, TOPIC_CLASSLOAD, req, GridIoPolicy.P2P_POOL);
if (log.isDebugEnabled())
log.debug("Sent peer class loading request [node=" + dstNode.id() + ", req=" + req + ']');
synchronized (qryMux) {
try {
long timeout = threshold - start;
if (log.isDebugEnabled()) {
log.debug("Waiting for peer response from node [node=" + dstNode.id() + ", timeout=" + timeout + ']');
}
while (res.get() == null && timeout > 0) {
qryMux.wait(timeout);
timeout = threshold - U.currentTimeMillis();
}
} catch (InterruptedException e) {
// Interrupt again to get it in the users code.
Thread.currentThread().interrupt();
throw new IgniteCheckedException("Got interrupted while waiting for response from node: " + dstNode.id(), e);
}
}
if (res.get() == null) {
U.warn(log, "Failed to receive peer response from node within duration [node=" + dstNode.id() + ", duration=" + (U.currentTimeMillis() - start) + ']');
} else if (log.isDebugEnabled())
log.debug("Received peer loading response [node=" + dstNode.id() + ", res=" + res.get() + ']');
return res.get();
} finally {
ctx.event().removeLocalEventListener(discoLsnr, EVT_NODE_FAILED, EVT_NODE_LEFT);
ctx.io().removeMessageListener(resTopic, resLsnr);
}
}
Aggregations