Search in sources :

Example 31 with GridCacheMvccCandidate

use of org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate 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 (checkDone())
            return;
        if (log.isDebugEnabled())
            log.debug("Mapped DHT lock future [dhtMap=" + F.nodeIds(dhtMap.keySet()) + ", dhtLockFut=" + this + ']');
        long timeout = inTx() ? tx.remainingTime() : this.timeout;
        synchronized (this) {
            // Prevents entry removal on concurrent rollback.
            if (checkDone())
                return;
            // 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.taskNameHash() : 0, read ? accessTtl : -1L, skipStore, cctx.store().configured(), keepBinary, cctx.deploymentEnabled(), inTx() ? tx.label() : null);
                    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;
                                }
                                // 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);
                                    }
                                }
                                GridCacheMvccCandidate added = e.candidate(lockVer);
                                assert added != null;
                                assert added.dhtLocal();
                                if (added.ownerVersion() != null)
                                    req.owned(e.key(), added.ownerVersion());
                            } catch (GridCacheEntryRemovedException ex) {
                                assert false : "Entry cannot become obsolete when DHT local candidate is added " + "[e=" + e + ", ex=" + ex + ']';
                            }
                        }
                        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();
    }
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) IgniteTxEntry(org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry) GridDhtInvalidPartitionException(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtInvalidPartitionException) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) List(java.util.List) ArrayList(java.util.ArrayList) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) LinkedHashMap(java.util.LinkedHashMap) GridCacheMvccCandidate(org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)

Example 32 with GridCacheMvccCandidate

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

the class GridDistributedCacheEntry method removeLock.

/**
 * {@inheritDoc}
 */
@Override
public boolean removeLock(GridCacheVersion ver) throws GridCacheEntryRemovedException {
    CacheLockCandidates prev = null;
    CacheLockCandidates owner = null;
    GridCacheMvccCandidate doomed;
    GridCacheVersion deferredDelVer;
    CacheObject val;
    cctx.tm().detectPossibleCollidingKeys(this);
    lockEntry();
    try {
        GridCacheMvcc mvcc = mvccExtras();
        doomed = mvcc == null ? null : mvcc.candidate(ver);
        if (doomed == null)
            addRemoved(ver);
        GridCacheVersion obsoleteVer = obsoleteVersionExtras();
        if (obsoleteVer != null && !obsoleteVer.equals(ver))
            checkObsolete();
        if (doomed != null) {
            prev = mvcc.allOwners();
            boolean emptyBefore = mvcc.isEmpty();
            mvcc.remove(doomed.version());
            boolean emptyAfter = mvcc.isEmpty();
            if (!doomed.local())
                refreshRemotes();
            checkCallbacks(emptyBefore, emptyAfter);
            if (emptyAfter)
                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 (log.isDebugEnabled())
        log.debug("Removed lock candidate from entry [doomed=" + doomed + ", owner=" + owner + ", prev=" + prev + ", entry=" + this + ']');
    if (doomed != null && doomed.nearLocal())
        cctx.mvcc().removeExplicitLock(doomed);
    if (doomed != null)
        checkThreadChain(doomed);
    // This call must be outside of synchronization.
    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) CacheLockCandidates(org.apache.ignite.internal.processors.cache.CacheLockCandidates) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) GridCacheMvccCandidate(org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate)

Example 33 with GridCacheMvccCandidate

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

the class GridDistributedCacheEntry method addLocal.

/**
 * Add local candidate.
 *
 * @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
public GridCacheMvccCandidate addLocal(long threadId, GridCacheVersion ver, AffinityTopologyVersion topVer, long timeout, boolean reenter, boolean tx, boolean implicitSingle, boolean read) throws GridCacheEntryRemovedException {
    GridCacheMvccCandidate cand;
    CacheLockCandidates prev;
    CacheLockCandidates owner;
    CacheObject val;
    lockEntry();
    try {
        checkObsolete();
        GridCacheMvcc mvcc = mvccExtras();
        if (mvcc == null) {
            mvcc = new GridCacheMvcc(cctx);
            mvccExtras(mvcc);
        }
        prev = mvcc.allOwners();
        boolean emptyBefore = mvcc.isEmpty();
        cand = mvcc.addLocal(this, threadId, ver, timeout, reenter, tx, implicitSingle, read);
        if (cand != null)
            cand.topologyVersion(topVer);
        owner = mvcc.allOwners();
        boolean emptyAfter = mvcc.isEmpty();
        checkCallbacks(emptyBefore, emptyAfter);
        val = this.val;
        if (emptyAfter)
            mvccExtras(null);
    } finally {
        unlockEntry();
    }
    // Don't link reentries.
    if (cand != null && !cand.reentry())
        // Link with other candidates in the same thread.
        cctx.mvcc().addNext(cctx, cand);
    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) GridCacheMvccCandidate(org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate) Nullable(org.jetbrains.annotations.Nullable)

Example 34 with GridCacheMvccCandidate

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

the class GridDistributedCacheEntry method removeLock.

/**
 * Unlocks local lock.
 *
 * @return Removed candidate, or <tt>null</tt> if thread still holds the lock.
 */
@Nullable
public GridCacheMvccCandidate removeLock() {
    GridCacheMvccCandidate rmvd = null;
    CacheLockCandidates prev = null;
    CacheLockCandidates owner = null;
    CacheObject val;
    cctx.tm().detectPossibleCollidingKeys(this);
    lockEntry();
    try {
        GridCacheMvcc mvcc = mvccExtras();
        if (mvcc != null) {
            prev = mvcc.allOwners();
            boolean emptyBefore = mvcc.isEmpty();
            rmvd = mvcc.releaseLocal();
            boolean emptyAfter = mvcc.isEmpty();
            checkCallbacks(emptyBefore, emptyAfter);
            if (emptyAfter)
                mvccExtras(null);
            else
                owner = mvcc.allOwners();
        }
        val = this.val;
    } finally {
        unlockEntry();
    }
    if (log.isDebugEnabled()) {
        log.debug("Released local candidate from entry [owner=" + owner + ", prev=" + prev + ", rmvd=" + rmvd + ", entry=" + this + ']');
    }
    if (prev != null) {
        for (int i = 0; i < prev.size(); i++) {
            GridCacheMvccCandidate cand = prev.candidate(i);
            checkThreadChain(cand);
        }
    }
    // This call must be outside of synchronization.
    checkOwnerChanged(prev, owner, val);
    return rmvd;
}
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) GridCacheMvccCandidate(org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate) Nullable(org.jetbrains.annotations.Nullable)

Example 35 with GridCacheMvccCandidate

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

the class GridDhtCacheEntry method addReader.

/**
 * @param nodeId Reader to add.
 * @param msgId Message ID.
 * @param topVer Topology version.
 * @return Future for all relevant transactions that were active at the time of adding reader,
 *      or {@code null} if reader was added
 * @throws GridCacheEntryRemovedException If entry was removed.
 */
@SuppressWarnings("unchecked")
@Nullable
public IgniteInternalFuture<Boolean> addReader(UUID nodeId, long msgId, AffinityTopologyVersion topVer) throws GridCacheEntryRemovedException {
    // Don't add local node as reader.
    if (cctx.nodeId().equals(nodeId))
        return null;
    ClusterNode node = cctx.discovery().node(nodeId);
    if (node == null) {
        if (log.isDebugEnabled())
            log.debug("Ignoring near reader because node left the grid: " + nodeId);
        return null;
    }
    // If remote node is (primary?) or back up, don't add it as a reader.
    if (cctx.affinity().partitionBelongs(node, partition(), topVer)) {
        if (log.isDebugEnabled())
            log.debug("Ignoring near reader because remote node is affinity node [locNodeId=" + cctx.localNodeId() + ", rmtNodeId=" + nodeId + ", key=" + key + ']');
        return null;
    }
    boolean ret = false;
    GridCacheMultiTxFuture txFut = null;
    Collection<GridCacheMvccCandidate> cands = null;
    ReaderId reader;
    lockEntry();
    try {
        checkObsolete();
        reader = readerId(nodeId);
        if (reader == null) {
            reader = new ReaderId(nodeId, msgId);
            ReaderId[] rdrs = Arrays.copyOf(this.rdrs, this.rdrs.length + 1);
            rdrs[rdrs.length - 1] = reader;
            // Seal.
            this.rdrs = rdrs;
            // No transactions in ATOMIC cache.
            if (!cctx.atomic()) {
                txFut = reader.getOrCreateTxFuture(cctx);
                cands = localCandidates();
                ret = true;
            }
        } else {
            txFut = reader.txFuture();
            long id = reader.messageId();
            if (id < msgId)
                reader.messageId(msgId);
        }
    } finally {
        unlockEntry();
    }
    if (ret) {
        assert txFut != null;
        if (!F.isEmpty(cands)) {
            for (GridCacheMvccCandidate c : cands) {
                IgniteInternalTx tx = cctx.tm().tx(c.version());
                if (tx != null && tx.local())
                    txFut.addTx(tx);
            }
        }
        txFut.init();
        if (!txFut.isDone()) {
            final ReaderId reader0 = reader;
            txFut.listen(new CI1<IgniteInternalFuture<?>>() {

                @Override
                public void apply(IgniteInternalFuture<?> f) {
                    cctx.kernalContext().closure().runLocalSafe(new GridPlainRunnable() {

                        @Override
                        public void run() {
                            lockEntry();
                            try {
                                // Release memory.
                                reader0.resetTxFuture();
                            } finally {
                                unlockEntry();
                            }
                        }
                    });
                }
            });
        } else {
            lockEntry();
            try {
                // Release memory.
                reader.resetTxFuture();
            } finally {
                unlockEntry();
            }
            txFut = null;
        }
    }
    return txFut;
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) GridPlainRunnable(org.apache.ignite.internal.util.lang.GridPlainRunnable) GridCacheMultiTxFuture(org.apache.ignite.internal.processors.cache.GridCacheMultiTxFuture) IgniteInternalTx(org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx) 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