Search in sources :

Example 26 with GridCacheMvccCandidate

use of org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate in project ignite by apache.

the class GridLocalCacheEntry method removeLock.

/**
 * {@inheritDoc}
 */
@Override
public boolean removeLock(GridCacheVersion ver) throws GridCacheEntryRemovedException {
    CacheObject val;
    CacheLockCandidates prev = null;
    CacheLockCandidates owner = null;
    GridCacheMvccCandidate doomed;
    GridCacheVersion deferredDelVer;
    lockEntry();
    try {
        GridCacheVersion obsoleteVer = obsoleteVersionExtras();
        if (obsoleteVer != null && !obsoleteVer.equals(ver))
            checkObsolete();
        GridCacheMvcc mvcc = mvccExtras();
        doomed = mvcc == null ? null : mvcc.candidate(ver);
        if (doomed != null) {
            prev = mvcc.allOwners();
            mvcc.remove(ver);
            if (mvcc.isEmpty())
                mvccExtras(null);
            else
                owner = mvcc.allOwners();
        }
        val = this.val;
        deferredDelVer = this.ver;
    } finally {
        unlockEntry();
    }
    if (val == null) {
        boolean deferred = cctx.deferredDelete() && !detached() && !isInternal();
        if (deferred) {
            if (deferredDelVer != null)
                cctx.onDeferredDelete(this, deferredDelVer);
        }
    }
    if (doomed != null)
        checkThreadChain(doomed);
    checkOwnerChanged(prev, owner, val);
    return doomed != null;
}
Also used : GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) GridCacheMvcc(org.apache.ignite.internal.processors.cache.GridCacheMvcc) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) CacheLockCandidates(org.apache.ignite.internal.processors.cache.CacheLockCandidates) GridCacheMvccCandidate(org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate)

Example 27 with GridCacheMvccCandidate

use of org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate in project ignite by apache.

the class GridNearLockFuture method map.

/**
 * Maps keys to nodes. Note that we can not simply group keys by nodes and send lock request as
 * such approach does not preserve order of lock acquisition. Instead, keys are split in continuous
 * groups belonging to one primary node and locks for these groups are acquired sequentially.
 *
 * @param keys Keys.
 * @param remap Remap flag.
 * @param topLocked {@code True} if thread already acquired lock preventing topology change.
 */
private void map(Iterable<KeyCacheObject> keys, boolean remap, boolean topLocked) {
    try {
        AffinityTopologyVersion topVer = this.topVer;
        assert topVer != null;
        assert topVer.topologyVersion() > 0 : topVer;
        if (CU.affinityNodes(cctx, topVer).isEmpty()) {
            onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for near-only cache (all " + "partition nodes left the grid)."));
            return;
        }
        boolean clientNode = cctx.kernalContext().clientNode();
        assert !remap || (clientNode && (tx == null || !tx.hasRemoteLocks()));
        synchronized (this) {
            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.nearLocallyMapped(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 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();
                assert !mappedKeys.isEmpty();
                GridNearLockRequest req = null;
                Collection<KeyCacheObject> distributedKeys = new ArrayList<>(mappedKeys.size());
                boolean explicit = false;
                for (KeyCacheObject key : mappedKeys) {
                    IgniteTxKey txKey = cctx.txKey(key);
                    while (true) {
                        GridNearCacheEntry entry = null;
                        try {
                            entry = cctx.near().entryExx(key, topVer);
                            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;
                            }
                            // Removed exception may be thrown here.
                            GridCacheMvccCandidate cand = addEntry(topVer, entry, node.id());
                            if (isDone()) {
                                if (log.isDebugEnabled())
                                    log.debug("Abandoning (re)map because future is done after addEntry attempt " + "[fut=" + this + ", entry=" + entry + ']');
                                return;
                            }
                            if (cand != null) {
                                if (tx == null && !cand.reentry())
                                    cctx.mvcc().addExplicitLock(threadId, cand, topVer);
                                IgniteBiTuple<GridCacheVersion, CacheObject> val = entry.versionedValue();
                                if (val == null) {
                                    GridDhtCacheEntry dhtEntry = dht().peekExx(key);
                                    try {
                                        if (dhtEntry != null)
                                            val = dhtEntry.versionedValue(topVer);
                                    } catch (GridCacheEntryRemovedException ignored) {
                                        assert dhtEntry.obsolete() : dhtEntry;
                                        if (log.isDebugEnabled())
                                            log.debug("Got removed exception for DHT entry in map (will ignore): " + dhtEntry);
                                    }
                                }
                                GridCacheVersion dhtVer = null;
                                if (val != null) {
                                    dhtVer = val.get1();
                                    valMap.put(key, val);
                                }
                                if (!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, true, cctx.deploymentEnabled(), inTx() ? tx.label() : null);
                                        mapping.request(req);
                                    }
                                    distributedKeys.add(key);
                                    if (tx != null)
                                        tx.addKeyMapping(txKey, mapping.node());
                                    req.addKeyBytes(key, retval && dhtVer == null, dhtVer, // Include DHT version to match remote DHT entry.
                                    cctx);
                                }
                                if (cand.reentry())
                                    explicit = tx != null && !entry.hasLockCandidate(tx.xidVersion());
                            } else {
                                if (timedOut)
                                    return;
                                // Ignore reentries within transactions.
                                explicit = tx != null && !entry.hasLockCandidate(tx.xidVersion());
                            }
                            if (explicit)
                                tx.addKeyMapping(txKey, mapping.node());
                            break;
                        } catch (GridCacheEntryRemovedException ignored) {
                            assert entry.obsolete() : "Got removed exception on non-obsolete entry: " + entry;
                            if (log.isDebugEnabled())
                                log.debug("Got removed entry in lockAsync(..) method (will retry): " + entry);
                        }
                    }
                    // 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);
                else {
                    assert mapping.request() == null;
                    iter.remove();
                }
            }
        }
        cctx.mvcc().recheckPendingLocks();
        proceedMapping();
    } catch (IgniteCheckedException ex) {
        onError(ex);
    }
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) ArrayList(java.util.ArrayList) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) GridDhtCacheEntry(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) 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 28 with GridCacheMvccCandidate

use of org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate in project ignite by apache.

the class GridNearTransactionalCache method removeLocks.

/**
 * Removes locks regardless of whether they are owned or not for given
 * version and keys.
 *
 * @param ver Lock version.
 * @param keys Keys.
 */
public void removeLocks(GridCacheVersion ver, Collection<KeyCacheObject> keys) {
    if (keys.isEmpty())
        return;
    try {
        int keyCnt = -1;
        Map<ClusterNode, GridNearUnlockRequest> map = null;
        for (KeyCacheObject key : keys) {
            // Send request to remove from remote nodes.
            GridNearUnlockRequest req = null;
            while (true) {
                GridDistributedCacheEntry entry = peekExx(key);
                try {
                    if (entry != null) {
                        GridCacheMvccCandidate cand = entry.candidate(ver);
                        if (cand != null) {
                            if (map == null) {
                                Collection<ClusterNode> affNodes = CU.affinityNodes(ctx, cand.topologyVersion());
                                if (F.isEmpty(affNodes))
                                    return;
                                keyCnt = (int) Math.ceil((double) keys.size() / affNodes.size());
                                map = U.newHashMap(affNodes.size());
                            }
                            ClusterNode primary = ctx.affinity().primaryByKey(key, cand.topologyVersion());
                            if (primary == null) {
                                if (log.isDebugEnabled())
                                    log.debug("Failed to unlock key (all partition nodes left the grid).");
                                break;
                            }
                            if (!primary.isLocal()) {
                                req = map.get(primary);
                                if (req == null) {
                                    map.put(primary, req = new GridNearUnlockRequest(ctx.cacheId(), keyCnt, ctx.deploymentEnabled()));
                                    req.version(ver);
                                }
                            }
                            // Remove candidate from local node first.
                            if (entry.removeLock(cand.version())) {
                                if (primary.isLocal()) {
                                    dht.removeLocks(primary.id(), ver, F.asList(key), true);
                                    assert req == null;
                                    continue;
                                }
                                req.addKey(entry.key(), ctx);
                            }
                        }
                    }
                    break;
                } catch (GridCacheEntryRemovedException ignored) {
                    if (log.isDebugEnabled())
                        log.debug("Attempted to remove lock from removed entry (will retry) [rmvVer=" + ver + ", entry=" + entry + ']');
                }
            }
        }
        if (map == null || map.isEmpty())
            return;
        IgnitePair<Collection<GridCacheVersion>> versPair = ctx.tm().versions(ver);
        Collection<GridCacheVersion> committed = versPair.get1();
        Collection<GridCacheVersion> rolledback = versPair.get2();
        for (Map.Entry<ClusterNode, GridNearUnlockRequest> mapping : map.entrySet()) {
            ClusterNode n = mapping.getKey();
            GridDistributedUnlockRequest req = mapping.getValue();
            if (!F.isEmpty(req.keys())) {
                req.completedVersions(committed, rolledback);
                // We don't wait for reply to this message.
                ctx.io().send(n, req, ctx.ioPolicy());
            }
        }
    } 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) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridDistributedUnlockRequest(org.apache.ignite.internal.processors.cache.distributed.GridDistributedUnlockRequest) Collection(java.util.Collection) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) Map(java.util.Map) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) GridCacheMvccCandidate(org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate)

Example 29 with GridCacheMvccCandidate

use of org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate in project ignite by apache.

the class GridNearCacheEntry method dhtNodeId.

/**
 * @param ver Version to set DHT node ID for.
 * @param dhtNodeId DHT node ID.
 * @return {@code true} if candidate was found.
 * @throws GridCacheEntryRemovedException If entry is removed.
 */
@Nullable
public GridCacheMvccCandidate dhtNodeId(GridCacheVersion ver, UUID dhtNodeId) throws GridCacheEntryRemovedException {
    lockEntry();
    try {
        checkObsolete();
        GridCacheMvcc mvcc = mvccExtras();
        GridCacheMvccCandidate cand = mvcc == null ? null : mvcc.candidate(ver);
        if (cand == null)
            return null;
        cand.otherNodeId(dhtNodeId);
        return cand;
    } finally {
        unlockEntry();
    }
}
Also used : GridCacheMvcc(org.apache.ignite.internal.processors.cache.GridCacheMvcc) GridCacheMvccCandidate(org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate) Nullable(org.jetbrains.annotations.Nullable)

Example 30 with GridCacheMvccCandidate

use of org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate in project ignite by apache.

the class GridNearCacheEntry method addNearLocal.

/**
 * Add near local candidate.
 *
 * @param dhtNodeId DHT node ID.
 * @param threadId Owning thread ID.
 * @param ver Lock version.
 * @param topVer Topology version.
 * @param timeout Timeout to acquire lock.
 * @param reenter Reentry flag.
 * @param tx Transaction flag.
 * @param implicitSingle Implicit flag.
 * @param read Read lock flag.
 * @return New candidate.
 * @throws GridCacheEntryRemovedException If entry has been removed.
 */
@Nullable
GridCacheMvccCandidate addNearLocal(@Nullable UUID dhtNodeId, long threadId, GridCacheVersion ver, AffinityTopologyVersion topVer, long timeout, boolean reenter, boolean tx, boolean implicitSingle, boolean read) throws GridCacheEntryRemovedException {
    CacheLockCandidates prev;
    CacheLockCandidates owner = null;
    GridCacheMvccCandidate cand;
    CacheObject val;
    UUID locId = cctx.nodeId();
    lockEntry();
    try {
        checkObsolete();
        GridCacheMvcc mvcc = mvccExtras();
        if (mvcc == null) {
            mvcc = new GridCacheMvcc(cctx);
            mvccExtras(mvcc);
        }
        GridCacheMvccCandidate c = mvcc.localCandidateByThreadOrVer(locId, threadId, ver);
        if (c != null)
            return reenter ? c.reenter() : null;
        prev = mvcc.allOwners();
        boolean emptyBefore = mvcc.isEmpty();
        // Lock could not be acquired.
        if (timeout < 0 && !emptyBefore)
            return null;
        // Local lock for near cache is a local lock.
        cand = mvcc.addNearLocal(this, locId, dhtNodeId, threadId, ver, tx, implicitSingle, read);
        cand.topologyVersion(topVer);
        boolean emptyAfter = mvcc.isEmpty();
        checkCallbacks(emptyBefore, emptyAfter);
        val = this.val;
        if (emptyAfter)
            mvccExtras(null);
        else
            owner = mvcc.allOwners();
    } finally {
        unlockEntry();
    }
    // This call must be outside of synchronization.
    checkOwnerChanged(prev, owner, val);
    return cand;
}
Also used : GridCacheMvcc(org.apache.ignite.internal.processors.cache.GridCacheMvcc) CacheLockCandidates(org.apache.ignite.internal.processors.cache.CacheLockCandidates) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) UUID(java.util.UUID) GridCacheMvccCandidate(org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

GridCacheMvccCandidate (org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate)41 KeyCacheObject (org.apache.ignite.internal.processors.cache.KeyCacheObject)17 GridCacheVersion (org.apache.ignite.internal.processors.cache.version.GridCacheVersion)15 Nullable (org.jetbrains.annotations.Nullable)14 GridCacheMvcc (org.apache.ignite.internal.processors.cache.GridCacheMvcc)13 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)11 ClusterNode (org.apache.ignite.cluster.ClusterNode)11 CacheObject (org.apache.ignite.internal.processors.cache.CacheObject)11 GridCacheEntryRemovedException (org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException)10 ArrayList (java.util.ArrayList)9 Map (java.util.Map)9 CacheLockCandidates (org.apache.ignite.internal.processors.cache.CacheLockCandidates)9 IgniteTxEntry (org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry)8 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)6 IgniteTxKey (org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey)6 UUID (java.util.UUID)5 ClusterTopologyCheckedException (org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)5 GridCacheEntryEx (org.apache.ignite.internal.processors.cache.GridCacheEntryEx)5 GridDistributedCacheEntry (org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry)5 Collection (java.util.Collection)4