use of org.apache.ignite.internal.cluster.ClusterTopologyCheckedException in project gridgain by gridgain.
the class GridIoManager method sendToGridTopic.
/**
* @param nodeId Id of destination node.
* @param topic Topic to send the message to.
* @param msg Message to send.
* @param plc Type of processing.
* @throws IgniteCheckedException Thrown in case of any errors.
*/
public void sendToGridTopic(UUID nodeId, GridTopic topic, Message msg, byte plc) throws IgniteCheckedException {
ClusterNode node = ctx.discovery().node(nodeId);
if (node == null)
throw new ClusterTopologyCheckedException("Failed to send message to node (has node left grid?): " + nodeId);
send(node, topic, topic.ordinal(), msg, plc, false, 0, false, null, false);
}
use of org.apache.ignite.internal.cluster.ClusterTopologyCheckedException in project gridgain by gridgain.
the class GridJobProcessor method handleException.
/**
* Handles errors that happened prior to job creation.
*
* @param node Sender node.
* @param req Job execution request.
* @param ex Exception that happened.
* @param endTime Job end time.
*/
private void handleException(ClusterNode node, GridJobExecuteRequest req, IgniteException ex, long endTime) {
UUID locNodeId = ctx.localNodeId();
ClusterNode sndNode = ctx.discovery().node(node.id());
if (sndNode == null) {
U.warn(log, "Failed to reply to sender node because it left grid [nodeId=" + node.id() + ", jobId=" + req.getJobId() + ']');
if (ctx.event().isRecordable(EVT_JOB_FAILED)) {
JobEvent evt = new JobEvent();
evt.jobId(req.getJobId());
evt.message("Job reply failed (original task node left grid): " + req.getJobId());
evt.node(ctx.discovery().localNode());
evt.taskName(req.getTaskName());
evt.taskClassName(req.getTaskClassName());
evt.taskSessionId(req.getSessionId());
evt.type(EVT_JOB_FAILED);
evt.taskNode(node);
evt.taskSubjectId(req.getSubjectId());
// Record job reply failure.
ctx.event().record(evt);
}
return;
}
try {
boolean loc = ctx.localNodeId().equals(sndNode.id()) && !ctx.config().isMarshalLocalJobs();
GridJobExecuteResponse jobRes = new GridJobExecuteResponse(locNodeId, req.getSessionId(), req.getJobId(), loc ? null : U.marshal(marsh, ex), ex, loc ? null : U.marshal(marsh, null), null, loc ? null : U.marshal(marsh, null), null, false, null);
if (req.isSessionFullSupport()) {
// Send response to designated job topic.
// Always go through communication to preserve order,
// if attributes are enabled.
// Job response topic.
Object topic = TOPIC_TASK.topic(req.getJobId(), locNodeId);
long timeout = endTime - U.currentTimeMillis();
if (timeout <= 0)
// Ignore the actual timeout and send response anyway.
timeout = 1;
// Send response to designated job topic.
// Always go through communication to preserve order.
ctx.io().sendOrderedMessage(sndNode, topic, jobRes, req.isInternal() ? MANAGEMENT_POOL : SYSTEM_POOL, timeout, false);
} else if (ctx.localNodeId().equals(sndNode.id()))
ctx.task().processJobExecuteResponse(ctx.localNodeId(), jobRes);
else
// Send response to common topic as unordered message.
ctx.io().sendToGridTopic(sndNode, TOPIC_TASK, jobRes, req.isInternal() ? MANAGEMENT_POOL : SYSTEM_POOL);
} catch (IgniteCheckedException e) {
// The only option here is to log, as we must assume that resending will fail too.
if ((e instanceof ClusterTopologyCheckedException) || isDeadNode(node.id()))
// Avoid stack trace for left nodes.
U.error(log, "Failed to reply to sender node because it left grid [nodeId=" + node.id() + ", jobId=" + req.getJobId() + ']');
else {
assert sndNode != null;
U.error(log, "Error sending reply for job [nodeId=" + sndNode.id() + ", jobId=" + req.getJobId() + ']', e);
}
if (ctx.event().isRecordable(EVT_JOB_FAILED)) {
JobEvent evt = new JobEvent();
evt.jobId(req.getJobId());
evt.message("Failed to send reply for job: " + req.getJobId());
evt.node(ctx.discovery().localNode());
evt.taskName(req.getTaskName());
evt.taskClassName(req.getTaskClassName());
evt.taskSessionId(req.getSessionId());
evt.type(EVT_JOB_FAILED);
evt.taskNode(node);
evt.taskSubjectId(req.getSubjectId());
// Record job reply failure.
ctx.event().record(evt);
}
}
}
use of org.apache.ignite.internal.cluster.ClusterTopologyCheckedException in project gridgain by gridgain.
the class GridDhtLockFuture method map.
/**
* @param entries Entries.
*/
private void map(Iterable<GridDhtCacheEntry> entries) {
synchronized (this) {
if (mapped)
return;
mapped = true;
}
try {
if (log.isDebugEnabled())
log.debug("Mapping entry for DHT lock future: " + this);
// Assign keys to primary nodes.
for (GridDhtCacheEntry entry : entries) {
try {
while (true) {
try {
cctx.dhtMap(nearNodeId, topVer, entry, tx == null ? lockVer : null, log, dhtMap, null);
GridCacheMvccCandidate cand = entry.candidate(lockVer);
// Possible in case of lock cancellation.
if (cand == null) {
onFailed(false);
// Will mark initialized in finally block.
return;
}
break;
} catch (GridCacheEntryRemovedException ignore) {
if (log.isDebugEnabled())
log.debug("Got removed entry when mapping DHT lock future (will retry): " + entry);
entry = cctx.dht().entryExx(entry.key(), topVer);
}
}
} catch (GridDhtInvalidPartitionException e) {
assert false : "DHT lock should never get invalid partition [err=" + e + ", fut=" + this + ']';
}
}
if (checkDone())
return;
if (log.isDebugEnabled())
log.debug("Mapped DHT lock future [dhtMap=" + F.nodeIds(dhtMap.keySet()) + ", dhtLockFut=" + this + ']');
long timeout = inTx() ? tx.remainingTime() : this.timeout;
synchronized (this) {
// Prevents entry removal on concurrent rollback.
if (checkDone())
return;
// Create mini futures.
for (Map.Entry<ClusterNode, List<GridDhtCacheEntry>> mapped : dhtMap.entrySet()) {
ClusterNode n = mapped.getKey();
List<GridDhtCacheEntry> dhtMapping = mapped.getValue();
int cnt = F.size(dhtMapping);
if (cnt > 0) {
assert !n.id().equals(cctx.localNodeId());
if (inTx() && tx.remainingTime() == -1)
return;
MiniFuture fut = new MiniFuture(n, dhtMapping);
GridDhtLockRequest req = new GridDhtLockRequest(cctx.cacheId(), nearNodeId, inTx() ? tx.nearXidVersion() : null, threadId, futId, fut.futureId(), lockVer, topVer, inTx(), read, isolation(), isInvalidate(), timeout, cnt, 0, inTx() ? tx.size() : cnt, inTx() ? tx.subjectId() : null, inTx() ? tx.taskNameHash() : 0, read ? accessTtl : -1L, skipStore, cctx.store().configured(), keepBinary, cctx.deploymentEnabled(), inTx() ? tx.label() : null);
try {
for (ListIterator<GridDhtCacheEntry> it = dhtMapping.listIterator(); it.hasNext(); ) {
GridDhtCacheEntry e = it.next();
boolean needVal = false;
try {
// Must unswap entry so that isNewLocked returns correct value.
e.unswap(false);
needVal = e.isNewLocked();
if (needVal) {
List<ClusterNode> owners = cctx.topology().owners(e.partition(), tx != null ? tx.topologyVersion() : cctx.affinity().affinityTopologyVersion());
// Do not preload if local node is partition owner.
if (owners.contains(cctx.localNode()))
needVal = false;
}
// Skip entry if it is not new and is not present in updated mapping.
if (tx != null && !needVal)
continue;
boolean invalidateRdr = e.readerId(n.id()) != null;
req.addDhtKey(e.key(), invalidateRdr, cctx);
if (needVal) {
// Mark last added key as needed to be preloaded.
req.markLastKeyForPreload();
if (tx != null) {
IgniteTxEntry txEntry = tx.entry(e.txKey());
// NOOP entries will be sent to backups on prepare step.
if (txEntry.op() == GridCacheOperation.READ)
txEntry.op(GridCacheOperation.NOOP);
}
}
GridCacheMvccCandidate added = e.candidate(lockVer);
assert added != null;
assert added.dhtLocal();
if (added.ownerVersion() != null)
req.owned(e.key(), added.ownerVersion());
} catch (GridCacheEntryRemovedException ex) {
assert false : "Entry cannot become obsolete when DHT local candidate is added " + "[e=" + e + ", ex=" + ex + ']';
}
}
if (!F.isEmpty(req.keys())) {
if (tx != null)
tx.addLockTransactionNode(n);
// Append new future.
add(fut);
cctx.io().send(n, req, cctx.ioPolicy());
if (msgLog.isDebugEnabled()) {
msgLog.debug("DHT lock fut, sent request [txId=" + nearLockVer + ", dhtTxId=" + lockVer + ", inTx=" + inTx() + ", nodeId=" + n.id() + ']');
}
}
} catch (IgniteCheckedException e) {
// Fail the whole thing.
if (e instanceof ClusterTopologyCheckedException)
fut.onResult();
else {
if (msgLog.isDebugEnabled()) {
msgLog.debug("DHT lock fut, failed to send request [txId=" + nearLockVer + ", dhtTxId=" + lockVer + ", inTx=" + inTx() + ", node=" + n.id() + ", err=" + e + ']');
}
fut.onResult(e);
}
}
}
}
}
} finally {
markInitialized();
}
}
use of org.apache.ignite.internal.cluster.ClusterTopologyCheckedException in project gridgain by gridgain.
the class GridPartitionedGetFuture method map.
/**
* @param keys Keys.
* @param mapped Mappings to check for duplicates.
* @param topVer Topology version on which keys should be mapped.
*/
@Override
protected void map(Collection<KeyCacheObject> keys, Map<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> mapped, AffinityTopologyVersion topVer) {
try (TraceSurroundings ignored = MTC.support(cctx.kernalContext().tracing().create(CACHE_API_GET_MAP, span))) {
MTC.span().addTag("topology.version", () -> Objects.toString(topVer));
GridDhtPartitionsExchangeFuture fut = cctx.shared().exchange().lastTopologyFuture();
// Finished DHT future is required for topology validation.
if (!fut.isDone()) {
if ((topVer.topologyVersion() > 0 && fut.initialVersion().after(topVer)) || (fut.exchangeActions() != null && fut.exchangeActions().hasStop()))
fut = cctx.shared().exchange().lastFinishedFuture();
else {
fut.listen(new IgniteInClosure<IgniteInternalFuture<AffinityTopologyVersion>>() {
@Override
public void apply(IgniteInternalFuture<AffinityTopologyVersion> fut) {
try {
AffinityTopologyVersion topVer0 = fut.get();
cctx.closures().runLocalSafe(new GridPlainRunnable() {
@Override
public void run() {
map(keys, mapped, topVer.topologyVersion() > 0 ? topVer : topVer0);
}
}, true);
} catch (IgniteCheckedException e) {
onDone(e);
}
}
});
return;
}
}
Collection<ClusterNode> cacheNodes = CU.affinityNodes(cctx, topVer);
validate(cacheNodes, fut);
// Future can be already done with some exception.
if (isDone())
return;
Map<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> mappings = U.newHashMap(cacheNodes.size());
int keysSize = keys.size();
// Map for local (key,value) pairs.
Map<K, V> locVals = U.newHashMap(keysSize);
// True if we have remote nodes after key mapping complete.
boolean hasRmtNodes = false;
// Assign keys to nodes.
for (KeyCacheObject key : keys) hasRmtNodes |= map(key, topVer, mappings, mapped, locVals);
// Future can be alredy done with some exception.
if (isDone())
return;
// Add local read (key,value) in result.
if (!locVals.isEmpty())
add(new GridFinishedFuture<>(locVals));
// If we have remote nodes in mapping we should registrate future in mvcc manager.
if (hasRmtNodes)
registrateFutureInMvccManager(this);
// Create mini futures after mapping to remote nodes.
for (Map.Entry<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> entry : mappings.entrySet()) {
// Node for request.
ClusterNode n = entry.getKey();
// Keys for request.
LinkedHashMap<KeyCacheObject, Boolean> mappedKeys = entry.getValue();
assert !mappedKeys.isEmpty();
// If this is the primary or backup node for the keys.
if (n.isLocal()) {
GridDhtFuture<Collection<GridCacheEntryInfo>> fut0 = cache().getDhtAsync(n.id(), -1, mappedKeys, false, readThrough, topVer, subjId, taskName == null ? 0 : taskName.hashCode(), expiryPlc, skipVals, recovery, txLbl, mvccSnapshot());
Collection<Integer> invalidParts = fut0.invalidPartitions();
if (!F.isEmpty(invalidParts)) {
Collection<KeyCacheObject> remapKeys = new ArrayList<>(keysSize);
for (KeyCacheObject key : keys) {
int part = cctx.affinity().partition(key);
if (key != null && invalidParts.contains(part)) {
addNodeAsInvalid(n, part, topVer);
remapKeys.add(key);
}
}
AffinityTopologyVersion updTopVer = cctx.shared().exchange().readyAffinityVersion();
// Remap recursively.
map(remapKeys, mappings, updTopVer);
}
// Add new future.
add(fut0.chain(f -> {
try {
return createResultMap(f.get());
} catch (Exception e) {
U.error(log, "Failed to get values from dht cache [fut=" + fut0 + "]", e);
onDone(e);
return Collections.emptyMap();
}
}));
} else {
MiniFuture miniFut = new MiniFuture(n, mappedKeys, topVer);
GridCacheMessage req = miniFut.createGetRequest(futId);
// Append new future.
add(miniFut);
try {
cctx.io().send(n, req, cctx.ioPolicy());
} catch (IgniteCheckedException e) {
// Fail the whole thing.
if (e instanceof ClusterTopologyCheckedException)
miniFut.onNodeLeft((ClusterTopologyCheckedException) e);
else
miniFut.onResult(e);
}
}
}
markInitialized();
}
}
use of org.apache.ignite.internal.cluster.ClusterTopologyCheckedException in project gridgain by gridgain.
the class GridPartitionedSingleGetFuture method map.
/**
* @param topVer Topology version.
*/
@SuppressWarnings("unchecked")
private void map(AffinityTopologyVersion topVer) {
try (TraceSurroundings ignored = MTC.support(cctx.kernalContext().tracing().create(CACHE_API_GET_MAP, span))) {
MTC.span().addTag("topology.version", () -> Objects.toString(topVer));
GridDhtPartitionsExchangeFuture fut = cctx.shared().exchange().lastTopologyFuture();
// Finished DHT future is required for topology validation.
if (!fut.isDone()) {
if ((topVer.topologyVersion() > 0 && fut.initialVersion().after(topVer)) || (fut.exchangeActions() != null && fut.exchangeActions().hasStop()))
fut = cctx.shared().exchange().lastFinishedFuture();
else {
fut.listen(new IgniteInClosure<IgniteInternalFuture<AffinityTopologyVersion>>() {
@Override
public void apply(IgniteInternalFuture<AffinityTopologyVersion> fut0) {
try {
AffinityTopologyVersion topVer0 = fut0.get();
cctx.closures().runLocalSafe(new GridPlainRunnable() {
@Override
public void run() {
map(topVer.topologyVersion() > 0 ? topVer : topVer0);
}
}, true);
} catch (IgniteCheckedException e) {
onDone(e);
}
}
});
return;
}
}
if (!validate(fut))
return;
ClusterNode node = mapKeyToNode(topVer);
if (node == null) {
assert isDone() : this;
return;
}
if (isDone())
return;
// Read value if node is localNode.
if (node.isLocal()) {
GridDhtFuture<GridCacheEntryInfo> fut0 = cctx.dht().getDhtSingleAsync(node.id(), -1, key, false, readThrough, topVer, subjId, taskName == null ? 0 : taskName.hashCode(), expiryPlc, skipVals, recovery, txLbl, mvccSnapshot);
Collection<Integer> invalidParts = fut0.invalidPartitions();
if (!F.isEmpty(invalidParts)) {
addNodeAsInvalid(node);
AffinityTopologyVersion updTopVer = cctx.shared().exchange().readyAffinityVersion();
// Remap recursively.
map(updTopVer);
} else {
fut0.listen(f -> {
try {
GridCacheEntryInfo info = f.get();
setResult(info);
} catch (Exception e) {
U.error(log, "Failed to get values from dht cache [fut=" + fut0 + "]", e);
onDone(e);
}
});
}
} else {
synchronized (this) {
assert this.node == null;
this.topVer = topVer;
this.node = node;
}
registrateFutureInMvccManager(this);
boolean needVer = this.needVer;
BackupPostProcessingClosure postClos = CU.createBackupPostProcessingClosure(topVer, log, cctx, key, expiryPlc, readThrough && cctx.readThroughConfigured(), skipVals);
if (postClos != null) {
// Need version to correctly store value.
needVer = true;
postProcessingClos = postClos;
}
GridCacheMessage req = new GridNearSingleGetRequest(cctx.cacheId(), futId.localId(), key, readThrough, topVer, subjId, taskName == null ? 0 : taskName.hashCode(), expiryPlc != null ? expiryPlc.forCreate() : -1L, expiryPlc != null ? expiryPlc.forAccess() : -1L, skipVals, /*add reader*/
false, needVer, cctx.deploymentEnabled(), recovery, txLbl, mvccSnapshot);
try {
cctx.io().send(node, req, cctx.ioPolicy());
} catch (IgniteCheckedException e) {
if (e instanceof ClusterTopologyCheckedException)
onNodeLeft(node.id());
else
onDone(e);
}
}
}
}
Aggregations