Search in sources :

Example 1 with GridDistributedCacheEntry

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);
        }
    }
}
Also used : GridDistributedCacheEntry(org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry)

Example 2 with GridDistributedCacheEntry

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();
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) IgniteTxEntry(org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry) GridDistributedCacheEntry(org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry) GridNearLockMapping(org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockMapping) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) GridNearLockRequest(org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest) ArrayList(java.util.ArrayList) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) ClusterTopologyServerNotFoundException(org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) IgniteTxKey(org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) GridCacheMvccCandidate(org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate)

Example 3 with GridDistributedCacheEntry

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);
    }
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) GridDistributedCacheEntry(org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) ArrayList(java.util.ArrayList) GridNearUnlockRequest(org.apache.ignite.internal.processors.cache.distributed.near.GridNearUnlockRequest) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridDistributedUnlockRequest(org.apache.ignite.internal.processors.cache.distributed.GridDistributedUnlockRequest) IgniteTxKey(org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey) Map(java.util.Map) GridCacheConcurrentMap(org.apache.ignite.internal.processors.cache.GridCacheConcurrentMap) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) GridCacheMvccCandidate(org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)

Example 4 with GridDistributedCacheEntry

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()));
        }
    }
}
Also used : GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) GridDistributedCacheEntry(org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException)

Example 5 with GridDistributedCacheEntry

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 + ']');
                }
            }
        }
    }
}
Also used : GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) GridDistributedCacheEntry(org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject)

Aggregations

GridDistributedCacheEntry (org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry)14 GridCacheEntryRemovedException (org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException)11 KeyCacheObject (org.apache.ignite.internal.processors.cache.KeyCacheObject)9 GridCacheVersion (org.apache.ignite.internal.processors.cache.version.GridCacheVersion)7 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)5 ClusterNode (org.apache.ignite.cluster.ClusterNode)5 GridCacheMvccCandidate (org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate)5 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)4 IgniteTxKey (org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey)4 ArrayList (java.util.ArrayList)3 Map (java.util.Map)3 ClusterTopologyCheckedException (org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)3 GridCacheContext (org.apache.ignite.internal.processors.cache.GridCacheContext)3 GridDistributedUnlockRequest (org.apache.ignite.internal.processors.cache.distributed.GridDistributedUnlockRequest)3 ClusterTopologyServerNotFoundException (org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException)2 CacheObject (org.apache.ignite.internal.processors.cache.CacheObject)2 IgniteTxEntry (org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry)2 IgniteTxRollbackCheckedException (org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException)2 Collection (java.util.Collection)1 LinkedList (java.util.LinkedList)1