use of org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry in project ignite by apache.
the class GridCacheMvccManager method removeExplicitNodeLocks.
/**
* @param leftNodeId Left node ID.
* @param topVer Topology version.
*/
public void removeExplicitNodeLocks(UUID leftNodeId, AffinityTopologyVersion topVer) {
for (GridDistributedCacheEntry entry : locked()) {
try {
entry.removeExplicitNodeLocks(leftNodeId);
entry.context().evicts().touch(entry, topVer);
} catch (GridCacheEntryRemovedException ignore) {
if (log.isDebugEnabled())
log.debug("Attempted to remove node locks from removed entry in mvcc manager " + "disco callback (will ignore): " + entry);
}
}
}
use of org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry in project ignite by apache.
the class GridDhtColocatedLockFuture method map0.
/**
* @param keys Keys to map.
* @param remap Remap flag.
* @param topLocked Topology locked flag.
* @throws IgniteCheckedException If mapping failed.
*/
private synchronized void map0(Collection<KeyCacheObject> keys, boolean remap, boolean topLocked) throws IgniteCheckedException {
try {
AffinityTopologyVersion topVer = this.topVer;
assert topVer != null;
assert topVer.topologyVersion() > 0;
if (CU.affinityNodes(cctx, topVer).isEmpty()) {
onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for cache " + "(all partition nodes left the grid): " + cctx.name()));
return;
}
boolean clientNode = cctx.kernalContext().clientNode();
assert !remap || (clientNode && (tx == null || !tx.hasRemoteLocks()));
// First assume this node is primary for all keys passed in.
if (!clientNode && mapAsPrimary(keys, topVer))
return;
mappings = new ArrayDeque<>();
// Assign keys to primary nodes.
GridNearLockMapping map = null;
for (KeyCacheObject key : keys) {
GridNearLockMapping updated = map(key, map, topVer);
// If new mapping was created, add to collection.
if (updated != map) {
mappings.add(updated);
if (tx != null && updated.node().isLocal())
tx.colocatedLocallyMapped(true);
}
map = updated;
}
if (isDone()) {
if (log.isDebugEnabled())
log.debug("Abandoning (re)map because future is done: " + this);
return;
}
if (log.isDebugEnabled())
log.debug("Starting (re)map for mappings [mappings=" + mappings + ", fut=" + this + ']');
boolean hasRmtNodes = false;
boolean first = true;
// Create mini futures.
for (Iterator<GridNearLockMapping> iter = mappings.iterator(); iter.hasNext(); ) {
GridNearLockMapping mapping = iter.next();
ClusterNode node = mapping.node();
Collection<KeyCacheObject> mappedKeys = mapping.mappedKeys();
boolean loc = node.equals(cctx.localNode());
assert !mappedKeys.isEmpty();
GridNearLockRequest req = null;
Collection<KeyCacheObject> distributedKeys = new ArrayList<>(mappedKeys.size());
for (KeyCacheObject key : mappedKeys) {
IgniteTxKey txKey = cctx.txKey(key);
GridDistributedCacheEntry entry = null;
if (tx != null) {
IgniteTxEntry txEntry = tx.entry(txKey);
if (txEntry != null) {
entry = (GridDistributedCacheEntry) txEntry.cached();
if (entry != null && loc == entry.detached()) {
entry = cctx.colocated().entryExx(key, topVer, true);
txEntry.cached(entry);
}
}
}
boolean explicit;
while (true) {
try {
if (entry == null)
entry = cctx.colocated().entryExx(key, topVer, true);
if (!cctx.isAll(entry, filter)) {
if (log.isDebugEnabled())
log.debug("Entry being locked did not pass filter (will not lock): " + entry);
onComplete(false, false);
return;
}
assert loc ^ entry.detached() : "Invalid entry [loc=" + loc + ", entry=" + entry + ']';
GridCacheMvccCandidate cand = addEntry(entry);
// Will either return value from dht cache or null if this is a miss.
IgniteBiTuple<GridCacheVersion, CacheObject> val = entry.detached() ? null : ((GridDhtCacheEntry) entry).versionedValue(topVer);
GridCacheVersion dhtVer = null;
if (val != null) {
dhtVer = val.get1();
valMap.put(key, val);
}
if (cand != null && !cand.reentry()) {
if (req == null) {
boolean clientFirst = false;
if (first) {
clientFirst = clientNode && !topLocked && (tx == null || !tx.hasRemoteLocks());
first = false;
}
assert !implicitTx() && !implicitSingleTx() : tx;
req = new GridNearLockRequest(cctx.cacheId(), topVer, cctx.nodeId(), threadId, futId, lockVer, inTx(), read, retval, isolation(), isInvalidate(), timeout, mappedKeys.size(), inTx() ? tx.size() : mappedKeys.size(), inTx() && tx.syncMode() == FULL_SYNC, inTx() ? tx.taskNameHash() : 0, read ? createTtl : -1L, read ? accessTtl : -1L, skipStore, keepBinary, clientFirst, false, cctx.deploymentEnabled(), inTx() ? tx.label() : null);
mapping.request(req);
}
distributedKeys.add(key);
if (tx != null)
tx.addKeyMapping(txKey, mapping.node());
req.addKeyBytes(key, retval, // Include DHT version to match remote DHT entry.
dhtVer, cctx);
}
explicit = inTx() && cand == null;
if (explicit)
tx.addKeyMapping(txKey, mapping.node());
break;
} catch (GridCacheEntryRemovedException ignored) {
if (log.isDebugEnabled())
log.debug("Got removed entry in lockAsync(..) method (will retry): " + entry);
entry = null;
}
}
// Mark mapping explicit lock flag.
if (explicit) {
boolean marked = tx != null && tx.markExplicit(node.id());
assert tx == null || marked;
}
}
if (!distributedKeys.isEmpty()) {
mapping.distributedKeys(distributedKeys);
hasRmtNodes |= !mapping.node().isLocal();
} else {
assert mapping.request() == null;
iter.remove();
}
}
} finally {
/**
* Notify ready {@link mappings} waiters. See {@link #cancel()}
*/
if (tx != null) {
mappingsReady = true;
notifyAll();
}
}
proceedMapping();
}
use of org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry 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.processors.cache.distributed.GridDistributedCacheEntry in project ignite by apache.
the class GridNearTxLocal method readyNearLock.
/**
* @param txEntry TX entry.
* @param dhtVer DHT version.
* @param pendingVers Pending versions.
* @param committedVers Committed versions.
* @param rolledbackVers Rolled back versions.
*/
private void readyNearLock(IgniteTxEntry txEntry, GridCacheVersion dhtVer, Collection<GridCacheVersion> pendingVers, Collection<GridCacheVersion> committedVers, Collection<GridCacheVersion> rolledbackVers) {
while (true) {
GridCacheContext cacheCtx = txEntry.cached().context();
assert cacheCtx.isNear();
GridDistributedCacheEntry entry = (GridDistributedCacheEntry) txEntry.cached();
try {
// Handle explicit locks.
GridCacheVersion explicit = txEntry.explicitVersion();
if (explicit == null) {
entry.readyNearLock(xidVer, dhtVer, committedVers, rolledbackVers, pendingVers);
}
break;
} catch (GridCacheEntryRemovedException ignored) {
assert entry.obsoleteVersion() != null;
if (log.isDebugEnabled())
log.debug("Replacing obsolete entry in remote transaction [entry=" + entry + ", tx=" + this + ']');
// Replace the entry.
txEntry.cached(txEntry.context().cache().entryEx(txEntry.key(), topologyVersion()));
}
}
}
use of org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry in project ignite by apache.
the class GridNearTransactionalCache method clearLocks.
/**
* @param nodeId Node ID.
* @param req Request.
*/
public void clearLocks(UUID nodeId, GridDhtUnlockRequest req) {
assert nodeId != null;
GridCacheVersion obsoleteVer = nextVersion();
List<KeyCacheObject> keys = req.nearKeys();
if (keys != null) {
AffinityTopologyVersion topVer = ctx.affinity().affinityTopologyVersion();
for (KeyCacheObject key : keys) {
while (true) {
GridDistributedCacheEntry entry = peekExx(key);
try {
if (entry != null) {
entry.doneRemote(req.version(), req.version(), null, req.committedVersions(), req.rolledbackVersions(), /*system invalidate*/
false);
// we are about to remove.
if (entry.removeLock(req.version())) {
if (log.isDebugEnabled())
log.debug("Removed lock [lockId=" + req.version() + ", key=" + key + ']');
// Try to evict near entry dht-mapped locally.
evictNearEntry(entry, obsoleteVer, topVer);
} else {
if (log.isDebugEnabled())
log.debug("Received unlock request for unknown candidate " + "(added to cancelled locks set): " + req);
}
entry.touch();
} else if (log.isDebugEnabled())
log.debug("Received unlock request for entry that could not be found: " + req);
break;
} catch (GridCacheEntryRemovedException ignored) {
if (log.isDebugEnabled())
log.debug("Received remove lock request for removed entry (will retry) [entry=" + entry + ", req=" + req + ']');
}
}
}
}
}
Aggregations