use of org.apache.ignite.internal.cluster.ClusterTopologyCheckedException in project ignite by apache.
the class GridDhtColocatedCache method unlockAll.
/**
* {@inheritDoc}
*/
@Override
public void unlockAll(Collection<? extends K> keys) {
if (keys.isEmpty())
return;
try {
GridCacheVersion ver = null;
int keyCnt = -1;
Map<ClusterNode, GridNearUnlockRequest> map = null;
Collection<KeyCacheObject> locKeys = new ArrayList<>();
for (K key : keys) {
KeyCacheObject cacheKey = ctx.toCacheKeyObject(key);
IgniteTxKey txKey = ctx.txKey(cacheKey);
GridDistributedCacheEntry entry = peekExx(cacheKey);
GridCacheMvccCandidate lock = ctx.mvcc().removeExplicitLock(Thread.currentThread().getId(), txKey, null);
if (lock != null) {
final AffinityTopologyVersion topVer = lock.topologyVersion();
assert topVer.compareTo(AffinityTopologyVersion.ZERO) > 0;
// Send request to remove from remote nodes.
ClusterNode primary = ctx.affinity().primaryByKey(key, topVer);
if (primary == null) {
if (log.isDebugEnabled())
log.debug("Failed to unlock keys (all partition nodes left the grid).");
continue;
}
if (map == null) {
Collection<ClusterNode> affNodes = CU.affinityNodes(ctx, topVer);
keyCnt = (int) Math.ceil((double) keys.size() / affNodes.size());
map = U.newHashMap(affNodes.size());
}
if (ver == null)
ver = lock.version();
if (!lock.reentry()) {
if (!ver.equals(lock.version()))
throw new IgniteCheckedException("Failed to unlock (if keys were locked separately, " + "then they need to be unlocked separately): " + keys);
if (!primary.isLocal()) {
GridNearUnlockRequest req = map.get(primary);
if (req == null) {
map.put(primary, req = new GridNearUnlockRequest(ctx.cacheId(), keyCnt, ctx.deploymentEnabled()));
req.version(ver);
}
KeyCacheObject key0 = entry != null ? entry.key() : cacheKey;
req.addKey(key0, ctx);
} else
locKeys.add(cacheKey);
if (log.isDebugEnabled())
log.debug("Removed lock (will distribute): " + lock);
} else if (log.isDebugEnabled())
log.debug("Current thread still owns lock (or there are no other nodes)" + " [lock=" + lock + ", curThreadId=" + Thread.currentThread().getId() + ']');
}
}
if (ver == null)
return;
if (!locKeys.isEmpty())
removeLocks(ctx.localNodeId(), ver, locKeys, true);
for (Map.Entry<ClusterNode, GridNearUnlockRequest> mapping : map.entrySet()) {
ClusterNode n = mapping.getKey();
GridDistributedUnlockRequest req = mapping.getValue();
assert !n.isLocal();
if (!F.isEmpty(req.keys())) {
try {
// We don't wait for reply to this message.
ctx.io().send(n, req, ctx.ioPolicy());
} catch (ClusterTopologyCheckedException e) {
if (log.isDebugEnabled())
log.debug("Failed to send unlock request (node has left the grid) [keys=" + req.keys() + ", n=" + n + ", e=" + e + ']');
} catch (IgniteCheckedException e) {
U.error(log, "Failed to send unlock request [keys=" + req.keys() + ", n=" + n + ']', e);
}
}
}
} catch (IgniteCheckedException ex) {
U.error(log, "Failed to unlock the lock for keys: " + keys, ex);
}
}
use of org.apache.ignite.internal.cluster.ClusterTopologyCheckedException in project ignite by apache.
the class GridDhtColocatedLockFuture method proceedMapping0.
/**
* Gets next near lock mapping and either acquires dht locks locally or sends near lock request to
* remote primary node.
*
* @throws IgniteCheckedException If mapping can not be completed.
*/
private void proceedMapping0() throws IgniteCheckedException {
GridNearLockMapping map;
// Fail fast if future is completed (in case of async rollback)
if (isDone()) {
clear();
return;
}
// Fail fast if the transaction is timed out.
if (tx != null && tx.remainingTime() == -1) {
GridDhtColocatedLockFuture.this.onDone(false, tx.timeoutException());
clear();
return;
}
synchronized (this) {
map = mappings.poll();
}
// If there are no more mappings to process or prepare has timed out, complete the future.
if (map == null)
return;
final GridNearLockRequest req = map.request();
final Collection<KeyCacheObject> mappedKeys = map.distributedKeys();
final ClusterNode node = map.node();
if (filter != null && filter.length != 0)
req.filter(filter, cctx);
if (node.isLocal())
lockLocally(mappedKeys, req.topologyVersion());
else {
final MiniFuture fut = new MiniFuture(node, mappedKeys, ++miniId);
req.miniId(fut.futureId());
// Append new future.
add(fut);
try {
cctx.io().send(node, req, cctx.ioPolicy());
if (msgLog.isDebugEnabled()) {
msgLog.debug("Collocated lock fut, sent request [txId=" + lockVer + ", inTx=" + inTx() + ", node=" + node.id() + ']');
}
} catch (ClusterTopologyCheckedException ex) {
assert fut != null;
fut.onResult(ex);
}
}
}
use of org.apache.ignite.internal.cluster.ClusterTopologyCheckedException in project ignite by apache.
the class GridDhtColocatedLockFuture method newTopologyException.
/**
* Creates new topology exception for cases when primary node leaves grid during mapping.
*
* @param nested Optional nested exception.
* @param nodeId Node ID.
* @return Topology exception with user-friendly message.
*/
private ClusterTopologyCheckedException newTopologyException(@Nullable Throwable nested, UUID nodeId) {
ClusterTopologyCheckedException topEx = new ClusterTopologyCheckedException("Failed to acquire lock for keys " + "(primary node left grid, retry transaction if possible) [keys=" + keys + ", node=" + nodeId + ']', nested);
topEx.retryReadyFuture(cctx.shared().nextAffinityReadyFuture(topVer));
return topEx;
}
use of org.apache.ignite.internal.cluster.ClusterTopologyCheckedException in project ignite by apache.
the class NearTxResultHandler method apply.
/**
* {@inheritDoc}
*/
@Override
public void apply(IgniteInternalFuture<GridCacheReturn> fut0) {
GridDhtTxAbstractEnlistFuture fut = (GridDhtTxAbstractEnlistFuture) fut0;
GridCacheContext<?, ?> cctx = fut.cctx;
GridDhtTxLocal tx = (GridDhtTxLocal) fut.tx;
UUID nearNodeId = fut.nearNodeId;
GridNearTxEnlistResponse res = createResponse(fut);
try {
cctx.io().send(nearNodeId, res, cctx.ioPolicy());
} catch (ClusterTopologyCheckedException e) {
fut.onNodeLeft(nearNodeId);
} catch (IgniteCheckedException e) {
U.error(fut.log, "Failed to send near enlist response (will rollback transaction) [" + "tx=" + CU.txString(tx) + ", node=" + nearNodeId + ", res=" + res + ']', e);
try {
tx.rollbackDhtLocalAsync();
} catch (Throwable e1) {
e.addSuppressed(e1);
}
throw new GridClosureException(e);
}
}
use of org.apache.ignite.internal.cluster.ClusterTopologyCheckedException in project ignite by apache.
the class GridCacheProcessor method resetCacheState.
/**
* Resets cache state after the cache has been moved to recovery state.
*
* @param cacheNames Cache names.
* @return Future that will be completed when state is changed for all caches.
*/
public IgniteInternalFuture<?> resetCacheState(Collection<String> cacheNames) throws ClusterTopologyCheckedException {
sharedCtx.tm().checkEmptyTransactions(() -> format(CHECK_EMPTY_TRANSACTIONS_ERROR_MSG_FORMAT, cacheNames, "resetCacheState"));
Collection<DynamicCacheChangeRequest> reqs = new ArrayList<>(cacheNames.size());
for (String cacheName : cacheNames) {
final IgniteInternalCache<Object, Object> cache0 = internalCache(cacheName);
if (cache0 == null)
continue;
// Check if all lost partitions has at least one affinity owner.
final Collection<Integer> lostParts = cache0.lostPartitions();
if (lostParts.isEmpty())
continue;
for (Integer part : lostParts) {
final Collection<ClusterNode> owners = cache0.affinity().mapPartitionToPrimaryAndBackups(part);
if (owners.isEmpty())
throw new ClusterTopologyCheckedException("Cannot reset lost partitions because no baseline nodes " + "are online [cache=" + cacheName + ", partition=" + part + ']');
}
DynamicCacheChangeRequest req = DynamicCacheChangeRequest.resetLostPartitions(ctx, cacheName);
reqs.add(req);
}
return initiateCacheChanges(reqs).stream().collect(IgniteCollectors.toCompoundFuture());
}
Aggregations