use of org.apache.ignite.internal.managers.communication.GridMessageListener in project ignite by apache.
the class GridJobProcessor method requestJobSiblings.
/**
* @param ses Session.
* @return Siblings.
* @throws IgniteCheckedException If failed.
*/
public Collection<ComputeJobSibling> requestJobSiblings(final ComputeTaskSession ses) throws IgniteCheckedException {
assert ses != null;
final UUID taskNodeId = ses.getTaskNodeId();
ClusterNode taskNode = ctx.discovery().node(taskNodeId);
if (taskNode == null)
throw new IgniteCheckedException("Node that originated task execution has left grid: " + taskNodeId);
// Tuple: error message-response.
final IgniteBiTuple<String, GridJobSiblingsResponse> t = new IgniteBiTuple<>();
final Lock lock = new ReentrantLock();
final Condition cond = lock.newCondition();
GridMessageListener msgLsnr = new GridMessageListener() {
@Override
public void onMessage(UUID nodeId, Object msg, byte plc) {
String err = null;
GridJobSiblingsResponse res = null;
if (!(msg instanceof GridJobSiblingsResponse))
err = "Received unexpected message: " + msg;
else if (!nodeId.equals(taskNodeId))
err = "Received job siblings response from unexpected node [taskNodeId=" + taskNodeId + ", nodeId=" + nodeId + ']';
else {
// Sender and message type are fine.
res = (GridJobSiblingsResponse) msg;
if (res.jobSiblings() == null) {
try {
res.unmarshalSiblings(marsh);
} catch (IgniteCheckedException e) {
U.error(log, "Failed to unmarshal job siblings.", e);
err = e.getMessage();
}
}
}
lock.lock();
try {
if (t.isEmpty()) {
t.set(err, res);
cond.signalAll();
}
} finally {
lock.unlock();
}
}
};
GridLocalEventListener discoLsnr = new GridLocalEventListener() {
@Override
public void onEvent(Event evt) {
assert evt instanceof DiscoveryEvent && (evt.type() == EVT_NODE_FAILED || evt.type() == EVT_NODE_LEFT) : "Unexpected event: " + evt;
DiscoveryEvent discoEvt = (DiscoveryEvent) evt;
if (taskNodeId.equals(discoEvt.eventNode().id())) {
lock.lock();
try {
if (t.isEmpty()) {
t.set("Node that originated task execution has left grid: " + taskNodeId, null);
cond.signalAll();
}
} finally {
lock.unlock();
}
}
}
};
boolean loc = ctx.localNodeId().equals(taskNodeId);
// 1. Create unique topic name.
Object topic = TOPIC_JOB_SIBLINGS.topic(ses.getId(), topicIdGen.getAndIncrement());
try {
// 2. Register listener.
ctx.io().addMessageListener(topic, msgLsnr);
// 3. Send message.
ctx.io().sendToGridTopic(taskNode, TOPIC_JOB_SIBLINGS, new GridJobSiblingsRequest(ses.getId(), loc ? topic : null, loc ? null : U.marshal(marsh, topic)), SYSTEM_POOL);
// 4. Listen to discovery events.
ctx.event().addLocalEventListener(discoLsnr, EVT_NODE_FAILED, EVT_NODE_LEFT);
// 5. Check whether node has left before disco listener has been installed.
taskNode = ctx.discovery().node(taskNodeId);
if (taskNode == null)
throw new IgniteCheckedException("Node that originated task execution has left grid: " + taskNodeId);
// 6. Wait for result.
lock.lock();
try {
long netTimeout = ctx.config().getNetworkTimeout();
if (t.isEmpty())
cond.await(netTimeout, MILLISECONDS);
if (t.isEmpty())
throw new IgniteCheckedException("Timed out waiting for job siblings (consider increasing" + "'networkTimeout' configuration property) [ses=" + ses + ", netTimeout=" + netTimeout + ']');
// Error is set?
if (t.get1() != null)
throw new IgniteCheckedException(t.get1());
else
// Return result
return t.get2().jobSiblings();
} catch (InterruptedException e) {
throw new IgniteCheckedException("Interrupted while waiting for job siblings response: " + ses, e);
} finally {
lock.unlock();
}
} finally {
ctx.io().removeMessageListener(topic, msgLsnr);
ctx.event().removeLocalEventListener(discoLsnr);
}
}
use of org.apache.ignite.internal.managers.communication.GridMessageListener 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 Response value.
* @throws IgniteCheckedException Thrown if there is no connection with remote node.
* @throws TimeoutException If request timed out.
*/
GridDeploymentResponse sendResourceRequest(final String rsrcName, IgniteUuid clsLdrId, final ClusterNode dstNode, long threshold) throws IgniteCheckedException, TimeoutException {
assert rsrcName != null;
assert dstNode != null;
assert clsLdrId != null;
Collection<UUID> nodeIds = activeReqNodeIds.get();
if (nodeIds != null && nodeIds.contains(dstNode.id())) {
throw new IgniteCheckedException("Node attempts to load resource from one of the requesters " + "[rsrcName=" + rsrcName + ", dstNodeId=" + dstNode.id() + ", requesters=" + nodeIds + ']');
}
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 = resourceDiscoListener(res, dstNode, rsrcName, qryMux);
GridMessageListener resLsnr = resourceMessageListener(res, qryMux);
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();
}
if (timeout <= 0)
throw new TimeoutException();
} catch (InterruptedException e) {
// Interrupt again to get it in the users code.
Thread.currentThread().interrupt();
TimeoutException te = new TimeoutException("Got interrupted while waiting for response from node: " + dstNode.id());
te.initCause(e);
throw te;
}
}
assert res.get() != null;
return res.get();
} finally {
ctx.event().removeLocalEventListener(discoLsnr, EVT_NODE_FAILED, EVT_NODE_LEFT);
ctx.io().removeMessageListener(resTopic, resLsnr);
}
}
use of org.apache.ignite.internal.managers.communication.GridMessageListener 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.
*/
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() {
@Override
public void onMessage(UUID nodeId, Object msg, byte plc) {
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 startNanos = System.nanoTime();
long passedMillis = 0L;
Collection<UUID> uidsCp = null;
synchronized (qryMux) {
try {
while (!uids.isEmpty() && err.get() == null && passedMillis < timeout) {
qryMux.wait(timeout - passedMillis);
passedMillis = U.millisSinceNanos(startNanos);
}
} 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.internal.managers.communication.GridMessageListener in project ignite by apache.
the class JobStealingCollisionSpi method onContextInitialized0.
/**
* {@inheritDoc}
*/
@Override
protected void onContextInitialized0(IgniteSpiContext spiCtx) throws IgniteSpiException {
spiCtx.addLocalEventListener(discoLsnr = new GridLocalEventListener() {
@Override
public void onEvent(Event evt) {
assert evt instanceof DiscoveryEvent;
DiscoveryEvent discoEvt = (DiscoveryEvent) evt;
UUID evtNodeId = discoEvt.eventNode().id();
switch(discoEvt.type()) {
case EVT_NODE_JOINED:
ClusterNode node = getSpiContext().node(evtNodeId);
if (node != null) {
nodeQueue.offer(node);
sndMsgMap.putIfAbsent(node.id(), new MessageInfo());
rcvMsgMap.putIfAbsent(node.id(), new MessageInfo());
}
break;
case EVT_NODE_LEFT:
case EVT_NODE_FAILED:
Iterator<ClusterNode> iter = nodeQueue.iterator();
while (iter.hasNext()) {
ClusterNode nextNode = iter.next();
if (nextNode.id().equals(evtNodeId))
iter.remove();
}
sndMsgMap.remove(evtNodeId);
rcvMsgMap.remove(evtNodeId);
break;
default:
assert false : "Unexpected event: " + evt;
}
}
}, EVT_NODE_FAILED, EVT_NODE_JOINED, EVT_NODE_LEFT);
Collection<ClusterNode> rmtNodes = spiCtx.remoteNodes();
for (ClusterNode node : rmtNodes) {
UUID id = node.id();
if (spiCtx.node(id) != null) {
sndMsgMap.putIfAbsent(id, new MessageInfo());
rcvMsgMap.putIfAbsent(id, new MessageInfo());
// Check if node has concurrently left.
if (spiCtx.node(id) == null) {
sndMsgMap.remove(id);
rcvMsgMap.remove(id);
}
}
}
nodeQueue.addAll(rmtNodes);
Iterator<ClusterNode> iter = nodeQueue.iterator();
while (iter.hasNext()) {
ClusterNode nextNode = iter.next();
if (spiCtx.node(nextNode.id()) == null)
iter.remove();
}
spiCtx.addMessageListener(msgLsnr = new GridMessageListener() {
@Override
public void onMessage(UUID nodeId, Object msg, byte plc) {
MessageInfo info = rcvMsgMap.get(nodeId);
if (info == null) {
if (log.isDebugEnabled())
log.debug("Ignoring message steal request as discovery event has not yet been received " + "for node: " + nodeId);
return;
}
int stealReqs0;
synchronized (info) {
JobStealingRequest req = (JobStealingRequest) msg;
// Increment total number of steal requests.
// Note that it is critical to increment total
// number of steal requests before resetting message info.
stealReqs0 = stealReqs.addAndGet(req.delta() - info.jobsToSteal());
info.reset(req.delta());
}
if (log.isDebugEnabled())
log.debug("Received steal request [nodeId=" + nodeId + ", msg=" + msg + ", stealReqs=" + stealReqs0 + ']');
CollisionExternalListener tmp = extLsnr;
// Let grid know that collisions should be resolved.
if (tmp != null)
tmp.onExternalCollision();
}
}, JOB_STEALING_COMM_TOPIC);
}
use of org.apache.ignite.internal.managers.communication.GridMessageListener in project ignite by apache.
the class GridP2PContinuousDeploymentClientDisconnectTest method blockClassLoadingRequest.
/**
* Blocks peer-class loading for {@link #P2P_TEST_OBJ_RSRC_NAME} resource.
*
* @param node The node where peer-class loading should be blocked.
*/
private void blockClassLoadingRequest(IgniteEx node) {
GridKernalContext ctx = node.context();
GridDeploymentManager deploymentMgr = ctx.deploy();
Object comm = GridTestUtils.getFieldValue(deploymentMgr, "comm");
GridMessageListener peerLsnr = GridTestUtils.getFieldValue(comm, "peerLsnr");
ctx.io().removeMessageListener(TOPIC_CLASSLOAD, peerLsnr);
GridMessageListener newPeerLsnr = new GridMessageListener() {
@Override
public void onMessage(UUID nodeId, Object msg, byte plc) {
GridDeploymentRequest req = (GridDeploymentRequest) msg;
String rsrcName = GridTestUtils.getFieldValue(req, "rsrcName");
if (rsrcName.equals(P2P_TEST_OBJ_RSRC_NAME))
return;
peerLsnr.onMessage(nodeId, msg, plc);
}
};
ctx.io().addMessageListener(TOPIC_CLASSLOAD, newPeerLsnr);
}
Aggregations