Search in sources :

Example 16 with KeyCacheObject

use of org.apache.ignite.internal.processors.cache.KeyCacheObject 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.allNodes(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 17 with KeyCacheObject

use of org.apache.ignite.internal.processors.cache.KeyCacheObject 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 {
    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.subjectId() : null, inTx() ? tx.taskNameHash() : 0, read ? createTtl : -1L, read ? accessTtl : -1L, skipStore, keepBinary, clientFirst, cctx.deploymentEnabled());
                            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();
        }
    }
    if (hasRmtNodes) {
        trackable = true;
        if (!remap && !cctx.mvcc().addFuture(this))
            throw new IllegalStateException("Duplicate future ID: " + this);
    } else
        trackable = false;
    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 18 with KeyCacheObject

use of org.apache.ignite.internal.processors.cache.KeyCacheObject 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;
    synchronized (this) {
        map = mappings.poll();
    }
    // If there are no more mappings to process, 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);
        IgniteInternalFuture<?> txSync = null;
        if (inTx())
            txSync = cctx.tm().awaitFinishAckAsync(node.id(), tx.threadId());
        if (txSync == null || txSync.isDone()) {
            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);
            }
        } else {
            txSync.listen(new CI1<IgniteInternalFuture<?>>() {

                @Override
                public void apply(IgniteInternalFuture<?> t) {
                    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);
                    } catch (IgniteCheckedException e) {
                        if (msgLog.isDebugEnabled()) {
                            msgLog.debug("Collocated lock fut, failed to send request [txId=" + lockVer + ", inTx=" + inTx() + ", node=" + node.id() + ", err=" + e + ']');
                        }
                        onError(e);
                    }
                }
            });
        }
    }
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridNearLockMapping(org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockMapping) GridNearLockRequest(org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)

Example 19 with KeyCacheObject

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

the class GridDhtColocatedLockFuture method lockLocally.

/**
     * Locks given keys directly through dht cache.
     * @param keys Collection of keys.
     * @param topVer Topology version to lock on.
     */
private void lockLocally(final Collection<KeyCacheObject> keys, AffinityTopologyVersion topVer) {
    if (log.isDebugEnabled())
        log.debug("Before locally locking keys : " + keys);
    IgniteInternalFuture<Exception> fut = cctx.colocated().lockAllAsync(cctx, tx, threadId, lockVer, topVer, keys, read, retval, timeout, createTtl, accessTtl, filter, skipStore, keepBinary);
    // Add new future.
    add(new GridEmbeddedFuture<>(new C2<Exception, Exception, Boolean>() {

        @Override
        public Boolean apply(Exception resEx, Exception e) {
            if (CU.isLockTimeoutOrCancelled(e) || (resEx != null && CU.isLockTimeoutOrCancelled(resEx)))
                return false;
            if (e != null) {
                onError(e);
                return false;
            }
            if (resEx != null) {
                onError(resEx);
                return false;
            }
            if (log.isDebugEnabled())
                log.debug("Acquired lock for local DHT mapping [locId=" + cctx.nodeId() + ", mappedKeys=" + keys + ", fut=" + GridDhtColocatedLockFuture.this + ']');
            if (inTx()) {
                for (KeyCacheObject key : keys) tx.entry(cctx.txKey(key)).markLocked();
            } else {
                for (KeyCacheObject key : keys) cctx.mvcc().markExplicitOwner(cctx.txKey(key), threadId);
            }
            try {
                // Proceed and add new future (if any) before completing embedded future.
                if (mappings != null)
                    proceedMapping();
            } catch (IgniteCheckedException ex) {
                onError(ex);
                return false;
            }
            return true;
        }
    }, fut));
}
Also used : IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteTxTimeoutCheckedException(org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) TransactionDeadlockException(org.apache.ignite.transactions.TransactionDeadlockException) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) GridCacheLockTimeoutException(org.apache.ignite.internal.processors.cache.GridCacheLockTimeoutException) ClusterTopologyServerNotFoundException(org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException) C2(org.apache.ignite.internal.util.typedef.C2) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject)

Example 20 with KeyCacheObject

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

the class GridDhtPreloader method processForceKeysRequest0.

/**
     * @param node Node originated request.
     * @param msg Force keys message.
     */
private void processForceKeysRequest0(ClusterNode node, GridDhtForceKeysRequest msg) {
    if (!enterBusy())
        return;
    try {
        ClusterNode loc = cctx.localNode();
        GridDhtForceKeysResponse res = new GridDhtForceKeysResponse(cctx.cacheId(), msg.futureId(), msg.miniId(), cctx.deploymentEnabled());
        for (KeyCacheObject k : msg.keys()) {
            int p = cctx.affinity().partition(k);
            GridDhtLocalPartition locPart = top.localPartition(p, AffinityTopologyVersion.NONE, false);
            // If this node is no longer an owner.
            if (locPart == null && !top.owners(p).contains(loc)) {
                res.addMissed(k);
                continue;
            }
            GridCacheEntryEx entry = null;
            while (true) {
                try {
                    entry = cctx.dht().entryEx(k);
                    entry.unswap();
                    GridCacheEntryInfo info = entry.info();
                    if (info == null) {
                        assert entry.obsolete() : entry;
                        continue;
                    }
                    if (!info.isNew())
                        res.addInfo(info);
                    cctx.evicts().touch(entry, msg.topologyVersion());
                    break;
                } catch (GridCacheEntryRemovedException ignore) {
                    if (log.isDebugEnabled())
                        log.debug("Got removed entry: " + k);
                } catch (GridDhtInvalidPartitionException ignore) {
                    if (log.isDebugEnabled())
                        log.debug("Local node is no longer an owner: " + p);
                    res.addMissed(k);
                    break;
                }
            }
        }
        if (log.isDebugEnabled())
            log.debug("Sending force key response [node=" + node.id() + ", res=" + res + ']');
        cctx.io().send(node, res, cctx.ioPolicy());
    } catch (ClusterTopologyCheckedException ignore) {
        if (log.isDebugEnabled())
            log.debug("Received force key request form failed node (will ignore) [nodeId=" + node.id() + ", req=" + msg + ']');
    } catch (IgniteCheckedException e) {
        U.error(log, "Failed to reply to force key request [nodeId=" + node.id() + ", req=" + msg + ']', e);
    } finally {
        leaveBusy();
    }
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) GridCacheEntryInfo(org.apache.ignite.internal.processors.cache.GridCacheEntryInfo) GridDhtInvalidPartitionException(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException) GridCacheEntryEx(org.apache.ignite.internal.processors.cache.GridCacheEntryEx) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) GridDhtLocalPartition(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLocalPartition) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)

Aggregations

KeyCacheObject (org.apache.ignite.internal.processors.cache.KeyCacheObject)105 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)65 GridCacheEntryRemovedException (org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException)56 CacheObject (org.apache.ignite.internal.processors.cache.CacheObject)54 GridCacheVersion (org.apache.ignite.internal.processors.cache.version.GridCacheVersion)41 ClusterTopologyCheckedException (org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)28 ArrayList (java.util.ArrayList)27 ClusterNode (org.apache.ignite.cluster.ClusterNode)27 Map (java.util.Map)25 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)23 GridCacheEntryEx (org.apache.ignite.internal.processors.cache.GridCacheEntryEx)23 EntryGetResult (org.apache.ignite.internal.processors.cache.EntryGetResult)15 HashMap (java.util.HashMap)14 IgniteException (org.apache.ignite.IgniteException)14 IgniteTxKey (org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey)14 LinkedHashMap (java.util.LinkedHashMap)13 IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)13 ClusterTopologyServerNotFoundException (org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException)13 CacheStorePartialUpdateException (org.apache.ignite.internal.processors.cache.CacheStorePartialUpdateException)12 NodeStoppingException (org.apache.ignite.internal.NodeStoppingException)11