use of org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException in project ignite by apache.
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 (isDone()) {
if (log.isDebugEnabled())
log.debug("Mapping won't proceed because future is done: " + this);
return;
}
if (log.isDebugEnabled())
log.debug("Mapped DHT lock future [dhtMap=" + F.nodeIds(dhtMap.keySet()) + ", dhtLockFut=" + this + ']');
long timeout = inTx() ? tx.remainingTime() : this.timeout;
// 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());
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;
}
} catch (GridCacheEntryRemovedException ex) {
assert false : "Entry cannot become obsolete when DHT local candidate is added " + "[e=" + e + ", ex=" + ex + ']';
}
// 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);
}
}
it.set(addOwned(req, e));
}
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.processors.cache.GridCacheEntryRemovedException in project ignite by apache.
the class GridDhtTransactionalCacheAdapter method lockAllAsyncInternal.
/**
* Acquires locks in partitioned cache.
*
* @param keys Keys to lock.
* @param timeout Lock timeout.
* @param txx Transaction.
* @param isInvalidate Invalidate flag.
* @param isRead Read flag.
* @param retval Return value flag.
* @param isolation Transaction isolation.
* @param createTtl TTL for create operation.
* @param accessTtl TTL for read operation.
* @param filter Optional filter.
* @param skipStore Skip store flag.
* @return Lock future.
*/
public GridDhtFuture<Boolean> lockAllAsyncInternal(@Nullable Collection<KeyCacheObject> keys, long timeout, IgniteTxLocalEx txx, boolean isInvalidate, boolean isRead, boolean retval, TransactionIsolation isolation, long createTtl, long accessTtl, CacheEntryPredicate[] filter, boolean skipStore, boolean keepBinary) {
if (keys == null || keys.isEmpty())
return new GridDhtFinishedFuture<>(true);
GridDhtTxLocalAdapter tx = (GridDhtTxLocalAdapter) txx;
assert tx != null;
GridDhtLockFuture fut = new GridDhtLockFuture(ctx, tx.nearNodeId(), tx.nearXidVersion(), tx.topologyVersion(), keys.size(), isRead, retval, timeout, tx, tx.threadId(), createTtl, accessTtl, filter, skipStore, keepBinary);
for (KeyCacheObject key : keys) {
try {
while (true) {
GridDhtCacheEntry entry = entryExx(key, tx.topologyVersion());
try {
fut.addEntry(entry);
// Possible in case of cancellation or time out.
if (fut.isDone())
return fut;
break;
} catch (GridCacheEntryRemovedException ignore) {
if (log.isDebugEnabled())
log.debug("Got removed entry when adding lock (will retry): " + entry);
} catch (GridDistributedLockCancelledException e) {
if (log.isDebugEnabled())
log.debug("Failed to add entry [err=" + e + ", entry=" + entry + ']');
return new GridDhtFinishedFuture<>(e);
}
}
} catch (GridDhtInvalidPartitionException e) {
fut.addInvalidPartition(ctx, e.partition());
if (log.isDebugEnabled())
log.debug("Added invalid partition to DHT lock future [part=" + e.partition() + ", fut=" + fut + ']');
}
}
ctx.mvcc().addFuture(fut);
fut.map();
return fut;
}
use of org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException in project ignite by apache.
the class GridDhtTransactionalCacheAdapter method processDhtLockRequest0.
/**
* @param nodeId Node ID.
* @param req Request.
*/
private void processDhtLockRequest0(UUID nodeId, GridDhtLockRequest req) {
assert nodeId != null;
assert req != null;
assert !nodeId.equals(locNodeId);
int cnt = F.size(req.keys());
GridDhtLockResponse res;
GridDhtTxRemote dhtTx = null;
GridNearTxRemote nearTx = null;
boolean fail = false;
boolean cancelled = false;
try {
res = new GridDhtLockResponse(ctx.cacheId(), req.version(), req.futureId(), req.miniId(), cnt, ctx.deploymentEnabled());
dhtTx = startRemoteTx(nodeId, req, res);
nearTx = isNearEnabled(cacheCfg) ? near().startRemoteTx(nodeId, req) : null;
if (nearTx != null && !nearTx.empty())
res.nearEvicted(nearTx.evicted());
else {
if (!F.isEmpty(req.nearKeys())) {
Collection<IgniteTxKey> nearEvicted = new ArrayList<>(req.nearKeys().size());
nearEvicted.addAll(F.viewReadOnly(req.nearKeys(), new C1<KeyCacheObject, IgniteTxKey>() {
@Override
public IgniteTxKey apply(KeyCacheObject k) {
return ctx.txKey(k);
}
}));
res.nearEvicted(nearEvicted);
}
}
} catch (IgniteTxRollbackCheckedException e) {
String err = "Failed processing DHT lock request (transaction has been completed): " + req;
U.error(log, err, e);
res = new GridDhtLockResponse(ctx.cacheId(), req.version(), req.futureId(), req.miniId(), new IgniteTxRollbackCheckedException(err, e), ctx.deploymentEnabled());
fail = true;
} catch (IgniteCheckedException e) {
String err = "Failed processing DHT lock request: " + req;
U.error(log, err, e);
res = new GridDhtLockResponse(ctx.cacheId(), req.version(), req.futureId(), req.miniId(), new IgniteCheckedException(err, e), ctx.deploymentEnabled());
fail = true;
} catch (GridDistributedLockCancelledException ignored) {
// Received lock request for cancelled lock.
if (log.isDebugEnabled())
log.debug("Received lock request for canceled lock (will ignore): " + req);
res = null;
fail = true;
cancelled = true;
}
boolean releaseAll = false;
if (res != null) {
try {
// Reply back to sender.
ctx.io().send(nodeId, res, ctx.ioPolicy());
if (txLockMsgLog.isDebugEnabled()) {
txLockMsgLog.debug("Sent dht lock response [txId=" + req.nearXidVersion() + ", dhtTxId=" + req.version() + ", inTx=" + req.inTx() + ", node=" + nodeId + ']');
}
} catch (ClusterTopologyCheckedException ignored) {
U.warn(txLockMsgLog, "Failed to send dht lock response, node failed [" + "txId=" + req.nearXidVersion() + ", dhtTxId=" + req.version() + ", inTx=" + req.inTx() + ", node=" + nodeId + ']');
fail = true;
releaseAll = true;
} catch (IgniteCheckedException e) {
U.error(txLockMsgLog, "Failed to send dht lock response (lock will not be acquired) " + "txId=" + req.nearXidVersion() + ", dhtTxId=" + req.version() + ", inTx=" + req.inTx() + ", node=" + nodeId + ']', e);
fail = true;
}
}
if (fail) {
if (dhtTx != null)
dhtTx.rollbackRemoteTx();
if (// Even though this should never happen, we leave this check for consistency.
nearTx != null)
nearTx.rollbackRemoteTx();
List<KeyCacheObject> keys = req.keys();
if (keys != null) {
for (KeyCacheObject key : keys) {
while (true) {
GridDistributedCacheEntry entry = peekExx(key);
try {
if (entry != null) {
// Release all locks because sender node left grid.
if (releaseAll)
entry.removeExplicitNodeLocks(req.nodeId());
else
entry.removeLock(req.version());
}
break;
} catch (GridCacheEntryRemovedException ignore) {
if (log.isDebugEnabled())
log.debug("Attempted to remove lock on removed entity during during failure " + "handling for dht lock request (will retry): " + entry);
}
}
}
}
if (releaseAll && !cancelled)
U.warn(log, "Sender node left grid in the midst of lock acquisition (locks have been released).");
}
}
use of org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException in project ignite by apache.
the class GridDhtTransactionalCacheAdapter method clearLocks.
/**
* @param nodeId Node ID.
* @param req Request.
*/
@SuppressWarnings({ "RedundantTypeArguments" })
private void clearLocks(UUID nodeId, GridDistributedUnlockRequest req) {
assert nodeId != null;
List<KeyCacheObject> keys = req.keys();
if (keys != null) {
for (KeyCacheObject key : keys) {
while (true) {
GridDistributedCacheEntry entry = peekExx(key);
if (entry == null)
// Nothing to unlock.
break;
try {
entry.doneRemote(req.version(), req.version(), null, null, null, /*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 + ']');
} else {
if (log.isDebugEnabled())
log.debug("Received unlock request for unknown candidate " + "(added to cancelled locks set): " + req);
}
ctx.evicts().touch(entry, ctx.affinity().affinityTopologyVersion());
break;
} catch (GridCacheEntryRemovedException ignored) {
if (log.isDebugEnabled())
log.debug("Received remove lock request for removed entry (will retry) [entry=" + entry + ", req=" + req + ']');
}
}
}
}
}
use of org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException in project ignite by apache.
the class GridDhtTransactionalCacheAdapter method removeLocks.
/**
* @param nodeId Node ID.
* @param ver Version.
* @param keys Keys.
* @param unmap Flag for un-mapping version.
*/
public void removeLocks(UUID nodeId, GridCacheVersion ver, Iterable<KeyCacheObject> keys, boolean unmap) {
assert nodeId != null;
assert ver != null;
if (F.isEmpty(keys))
return;
// Remove mapped versions.
GridCacheVersion dhtVer = unmap ? ctx.mvcc().unmapVersion(ver) : ver;
Map<ClusterNode, List<KeyCacheObject>> dhtMap = new HashMap<>();
Map<ClusterNode, List<KeyCacheObject>> nearMap = new HashMap<>();
GridCacheVersion obsoleteVer = null;
for (KeyCacheObject key : keys) {
while (true) {
boolean created = false;
GridDhtCacheEntry entry = peekExx(key);
if (entry == null) {
entry = entryExx(key);
created = true;
}
try {
GridCacheMvccCandidate cand = null;
if (dhtVer == null) {
cand = entry.localCandidateByNearVersion(ver, true);
if (cand != null)
dhtVer = cand.version();
else {
if (log.isDebugEnabled())
log.debug("Failed to locate lock candidate based on dht or near versions [nodeId=" + nodeId + ", ver=" + ver + ", unmap=" + unmap + ", keys=" + keys + ']');
entry.removeLock(ver);
if (created) {
if (obsoleteVer == null)
obsoleteVer = ctx.versions().next();
if (entry.markObsolete(obsoleteVer))
removeEntry(entry);
}
break;
}
}
if (cand == null)
cand = entry.candidate(dhtVer);
AffinityTopologyVersion topVer = cand == null ? AffinityTopologyVersion.NONE : cand.topologyVersion();
// Note that we obtain readers before lock is removed.
// Even in case if entry would be removed just after lock is removed,
// we must send release messages to backups and readers.
Collection<UUID> readers = entry.readers();
// we are about to remove.
if (entry.removeLock(dhtVer)) {
// Map to backups and near readers.
map(nodeId, topVer, entry, readers, dhtMap, nearMap);
if (log.isDebugEnabled())
log.debug("Removed lock [lockId=" + ver + ", key=" + key + ']');
} else if (log.isDebugEnabled())
log.debug("Received unlock request for unknown candidate " + "(added to cancelled locks set) [ver=" + ver + ", entry=" + entry + ']');
if (created && entry.markObsolete(dhtVer))
removeEntry(entry);
ctx.evicts().touch(entry, topVer);
break;
} catch (GridCacheEntryRemovedException ignored) {
if (log.isDebugEnabled())
log.debug("Received remove lock request for removed entry (will retry): " + entry);
} catch (IgniteCheckedException e) {
U.error(log, "Failed to remove locks for keys: " + keys, e);
}
}
}
IgnitePair<Collection<GridCacheVersion>> versPair = ctx.tm().versions(ver);
Collection<GridCacheVersion> committed = versPair.get1();
Collection<GridCacheVersion> rolledback = versPair.get2();
// Backups.
for (Map.Entry<ClusterNode, List<KeyCacheObject>> entry : dhtMap.entrySet()) {
ClusterNode n = entry.getKey();
List<KeyCacheObject> keyBytes = entry.getValue();
GridDhtUnlockRequest req = new GridDhtUnlockRequest(ctx.cacheId(), keyBytes.size(), ctx.deploymentEnabled());
req.version(dhtVer);
try {
for (KeyCacheObject key : keyBytes) req.addKey(key, ctx);
keyBytes = nearMap.get(n);
if (keyBytes != null)
for (KeyCacheObject key : keyBytes) req.addNearKey(key);
req.completedVersions(committed, rolledback);
ctx.io().send(n, req, ctx.ioPolicy());
} catch (ClusterTopologyCheckedException ignore) {
if (log.isDebugEnabled())
log.debug("Node left while sending unlock request: " + n);
} catch (IgniteCheckedException e) {
U.error(log, "Failed to send unlock request to node (will make best effort to complete): " + n, e);
}
}
// Readers.
for (Map.Entry<ClusterNode, List<KeyCacheObject>> entry : nearMap.entrySet()) {
ClusterNode n = entry.getKey();
if (!dhtMap.containsKey(n)) {
List<KeyCacheObject> keyBytes = entry.getValue();
GridDhtUnlockRequest req = new GridDhtUnlockRequest(ctx.cacheId(), keyBytes.size(), ctx.deploymentEnabled());
req.version(dhtVer);
try {
for (KeyCacheObject key : keyBytes) req.addNearKey(key);
req.completedVersions(committed, rolledback);
ctx.io().send(n, req, ctx.ioPolicy());
} catch (ClusterTopologyCheckedException ignore) {
if (log.isDebugEnabled())
log.debug("Node left while sending unlock request: " + n);
} catch (IgniteCheckedException e) {
U.error(log, "Failed to send unlock request to node (will make best effort to complete): " + n, e);
}
}
}
}
Aggregations