Search in sources :

Example 11 with GridCacheVersion

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

the class GridCacheMvcc method readyNearLocal.

/**
     * Marks near-local candidate as ready and makes locks reassignment. Following reorderings are performed when
     * candidate is marked ready:
     * <ul>
     *     <li/> All candidates preceding ready one are moved right after it.
     *     <li/> Near local candidate is assigned a mapped dht version. All remote non-pending candidates with
     *          version less then mapped dht version are marked as owned.
     * </ul>
     *
     * @param ver Version to mark as ready.
     * @param mappedVer Mapped dht version.
     * @param committedVers Committed versions.
     * @param rolledBackVers Rolled back versions.
     * @param pending Pending dht versions that are not owned and which version is less then mapped.
     * @return Lock owner after reassignment.
     */
@Nullable
public CacheLockCandidates readyNearLocal(GridCacheVersion ver, GridCacheVersion mappedVer, Collection<GridCacheVersion> committedVers, Collection<GridCacheVersion> rolledBackVers, Collection<GridCacheVersion> pending) {
    GridCacheMvccCandidate cand = candidate(locs, ver);
    if (cand != null) {
        assert cand.nearLocal() : "Near local candidate is not marked as near local: " + cand;
        cand.setReady();
        boolean setMapped = cand.otherVersion(mappedVer);
        assert setMapped : "Failed to set mapped dht version for near local candidate [mappedVer=" + mappedVer + ", cand=" + cand + ']';
        // For near locals we move all not owned candidates after this one.
        List<GridCacheMvccCandidate> mvAfter = null;
        for (ListIterator<GridCacheMvccCandidate> it = locs.listIterator(); it.hasNext(); ) {
            GridCacheMvccCandidate c = it.next();
            assert c.nearLocal() : "Near local candidate is not marked as near local: " + c;
            if (c == cand) {
                if (mvAfter != null)
                    for (GridCacheMvccCandidate mv : mvAfter) it.add(mv);
                break;
            } else {
                if (c.owner())
                    continue;
                assert !c.ready() || (c.read() && cand.read()) : "Cannot have more then one ready near-local candidate [c=" + c + ", cand=" + cand + ", mvcc=" + this + ']';
                it.remove();
                if (mvAfter == null)
                    mvAfter = new LinkedList<>();
                mvAfter.add(c);
            }
        }
        // Mark all remote candidates with less version as owner unless it is pending.
        if (rmts != null) {
            for (GridCacheMvccCandidate rmt : rmts) {
                GridCacheVersion rmtVer = rmt.version();
                if (rmtVer.isLess(mappedVer)) {
                    if (!pending.contains(rmtVer) && !mappedVer.equals(rmt.ownerVersion()))
                        rmt.setOwner();
                } else {
                    // Remote version is greater, so need to check if it was committed or rolled back.
                    if (committedVers.contains(rmtVer) || rolledBackVers.contains(rmtVer))
                        rmt.setOwner();
                }
            }
        }
        reassign();
    }
    return allOwners();
}
Also used : GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) LinkedList(java.util.LinkedList) Nullable(org.jetbrains.annotations.Nullable)

Example 12 with GridCacheVersion

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

the class GridDhtTransactionalCacheAdapter method lockAllAsync.

/**
     * @param cacheCtx Cache context.
     * @param nearNode Near node.
     * @param req Request.
     * @param filter0 Filter.
     * @return Future.
     */
public IgniteInternalFuture<GridNearLockResponse> lockAllAsync(final GridCacheContext<?, ?> cacheCtx, final ClusterNode nearNode, final GridNearLockRequest req, @Nullable final CacheEntryPredicate[] filter0) {
    final List<KeyCacheObject> keys = req.keys();
    CacheEntryPredicate[] filter = filter0;
    // Set message into thread context.
    GridDhtTxLocal tx = null;
    try {
        int cnt = keys.size();
        if (req.inTx()) {
            GridCacheVersion dhtVer = ctx.tm().mappedVersion(req.version());
            if (dhtVer != null)
                tx = ctx.tm().tx(dhtVer);
        }
        final List<GridCacheEntryEx> entries = new ArrayList<>(cnt);
        // Unmarshal filter first.
        if (filter == null)
            filter = req.filter();
        GridDhtLockFuture fut = null;
        if (!req.inTx()) {
            GridDhtPartitionTopology top = null;
            if (req.firstClientRequest()) {
                assert CU.clientNode(nearNode);
                top = topology();
                topology().readLock();
            }
            try {
                if (top != null && needRemap(req.topologyVersion(), top.topologyVersion())) {
                    if (log.isDebugEnabled()) {
                        log.debug("Client topology version mismatch, need remap lock request [" + "reqTopVer=" + req.topologyVersion() + ", locTopVer=" + top.topologyVersion() + ", req=" + req + ']');
                    }
                    GridNearLockResponse res = sendClientLockRemapResponse(nearNode, req, top.topologyVersion());
                    return new GridFinishedFuture<>(res);
                }
                fut = new GridDhtLockFuture(ctx, nearNode.id(), req.version(), req.topologyVersion(), cnt, req.txRead(), req.needReturnValue(), req.timeout(), tx, req.threadId(), req.createTtl(), req.accessTtl(), filter, req.skipStore(), req.keepBinary());
                // Add before mapping.
                if (!ctx.mvcc().addFuture(fut))
                    throw new IllegalStateException("Duplicate future ID: " + fut);
            } finally {
                if (top != null)
                    top.readUnlock();
            }
        }
        boolean timedout = false;
        for (KeyCacheObject key : keys) {
            if (timedout)
                break;
            while (true) {
                // Specify topology version to make sure containment is checked
                // based on the requested version, not the latest.
                GridDhtCacheEntry entry = entryExx(key, req.topologyVersion());
                try {
                    if (fut != null) {
                        // This method will add local candidate.
                        // Entry cannot become obsolete after this method succeeded.
                        fut.addEntry(key == null ? null : entry);
                        if (fut.isDone()) {
                            timedout = true;
                            break;
                        }
                    }
                    entries.add(entry);
                    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("Got lock request for cancelled lock (will ignore): " + entry);
                    fut.onError(e);
                    return new GridDhtFinishedFuture<>(e);
                }
            }
        }
        // Handle implicit locks for pessimistic transactions.
        if (req.inTx()) {
            if (tx == null) {
                GridDhtPartitionTopology top = null;
                if (req.firstClientRequest()) {
                    assert CU.clientNode(nearNode);
                    top = topology();
                    topology().readLock();
                }
                try {
                    if (top != null && needRemap(req.topologyVersion(), top.topologyVersion())) {
                        if (log.isDebugEnabled()) {
                            log.debug("Client topology version mismatch, need remap lock request [" + "reqTopVer=" + req.topologyVersion() + ", locTopVer=" + top.topologyVersion() + ", req=" + req + ']');
                        }
                        GridNearLockResponse res = sendClientLockRemapResponse(nearNode, req, top.topologyVersion());
                        return new GridFinishedFuture<>(res);
                    }
                    tx = new GridDhtTxLocal(ctx.shared(), req.topologyVersion(), nearNode.id(), req.version(), req.futureId(), req.miniId(), req.threadId(), /*implicitTx*/
                    false, /*implicitSingleTx*/
                    false, ctx.systemTx(), false, ctx.ioPolicy(), PESSIMISTIC, req.isolation(), req.timeout(), req.isInvalidate(), !req.skipStore(), false, req.txSize(), null, req.subjectId(), req.taskNameHash());
                    if (req.syncCommit())
                        tx.syncMode(FULL_SYNC);
                    tx = ctx.tm().onCreated(null, tx);
                    if (tx == null || !tx.init()) {
                        String msg = "Failed to acquire lock (transaction has been completed): " + req.version();
                        U.warn(log, msg);
                        if (tx != null)
                            tx.rollbackDhtLocal();
                        return new GridDhtFinishedFuture<>(new IgniteCheckedException(msg));
                    }
                    tx.topologyVersion(req.topologyVersion());
                } finally {
                    if (top != null)
                        top.readUnlock();
                }
            }
            ctx.tm().txContext(tx);
            if (log.isDebugEnabled())
                log.debug("Performing DHT lock [tx=" + tx + ", entries=" + entries + ']');
            IgniteInternalFuture<GridCacheReturn> txFut = tx.lockAllAsync(cacheCtx, entries, req.messageId(), req.txRead(), req.needReturnValue(), req.createTtl(), req.accessTtl(), req.skipStore(), req.keepBinary());
            final GridDhtTxLocal t = tx;
            return new GridDhtEmbeddedFuture(txFut, new C2<GridCacheReturn, Exception, IgniteInternalFuture<GridNearLockResponse>>() {

                @Override
                public IgniteInternalFuture<GridNearLockResponse> apply(GridCacheReturn o, Exception e) {
                    if (e != null)
                        e = U.unwrap(e);
                    assert !t.empty();
                    // Create response while holding locks.
                    final GridNearLockResponse resp = createLockReply(nearNode, entries, req, t, t.xidVersion(), e);
                    assert !t.implicit() : t;
                    assert !t.onePhaseCommit() : t;
                    sendLockReply(nearNode, t, req, resp);
                    return new GridFinishedFuture<>(resp);
                }
            });
        } else {
            assert fut != null;
            // This will send remote messages.
            fut.map();
            final GridCacheVersion mappedVer = fut.version();
            return new GridDhtEmbeddedFuture<>(new C2<Boolean, Exception, GridNearLockResponse>() {

                @Override
                public GridNearLockResponse apply(Boolean b, Exception e) {
                    if (e != null)
                        e = U.unwrap(e);
                    else if (!b)
                        e = new GridCacheLockTimeoutException(req.version());
                    GridNearLockResponse res = createLockReply(nearNode, entries, req, null, mappedVer, e);
                    sendLockReply(nearNode, null, req, res);
                    return res;
                }
            }, fut);
        }
    } catch (IgniteCheckedException | RuntimeException e) {
        String err = "Failed to unmarshal at least one of the keys for lock request message: " + req;
        U.error(log, err, e);
        if (tx != null) {
            try {
                tx.rollbackDhtLocal();
            } catch (IgniteCheckedException ex) {
                U.error(log, "Failed to rollback the transaction: " + tx, ex);
            }
        }
        return new GridDhtFinishedFuture<>(new IgniteCheckedException(err, e));
    }
}
Also used : GridDistributedLockCancelledException(org.apache.ignite.internal.processors.cache.distributed.GridDistributedLockCancelledException) ArrayList(java.util.ArrayList) GridNearLockResponse(org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse) GridCacheLockTimeoutException(org.apache.ignite.internal.processors.cache.GridCacheLockTimeoutException) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) GridFinishedFuture(org.apache.ignite.internal.util.future.GridFinishedFuture) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) GridCacheReturn(org.apache.ignite.internal.processors.cache.GridCacheReturn) IgniteTxRollbackCheckedException(org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) NodeStoppingException(org.apache.ignite.internal.NodeStoppingException) GridCacheLockTimeoutException(org.apache.ignite.internal.processors.cache.GridCacheLockTimeoutException) GridDistributedLockCancelledException(org.apache.ignite.internal.processors.cache.distributed.GridDistributedLockCancelledException) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException) GridClosureException(org.apache.ignite.internal.util.lang.GridClosureException) GridCacheEntryEx(org.apache.ignite.internal.processors.cache.GridCacheEntryEx) CacheEntryPredicate(org.apache.ignite.internal.processors.cache.CacheEntryPredicate)

Example 13 with GridCacheVersion

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

the class GridDhtTransactionalCacheAdapter method createLockReply.

/**
     * @param nearNode Near node.
     * @param entries Entries.
     * @param req Lock request.
     * @param tx Transaction.
     * @param mappedVer Mapped version.
     * @param err Error.
     * @return Response.
     */
private GridNearLockResponse createLockReply(ClusterNode nearNode, List<GridCacheEntryEx> entries, GridNearLockRequest req, @Nullable GridDhtTxLocalAdapter tx, GridCacheVersion mappedVer, Throwable err) {
    assert mappedVer != null;
    assert tx == null || tx.xidVersion().equals(mappedVer);
    try {
        // Send reply back to originating near node.
        GridNearLockResponse res = new GridNearLockResponse(ctx.cacheId(), req.version(), req.futureId(), req.miniId(), tx != null && tx.onePhaseCommit(), entries.size(), err, null, ctx.deploymentEnabled());
        if (err == null) {
            res.pending(localDhtPendingVersions(entries, mappedVer));
            // We have to add completed versions for cases when nearLocal and remote transactions
            // execute concurrently.
            IgnitePair<Collection<GridCacheVersion>> versPair = ctx.tm().versions(req.version());
            res.completedVersions(versPair.get1(), versPair.get2());
            int i = 0;
            for (ListIterator<GridCacheEntryEx> it = entries.listIterator(); it.hasNext(); ) {
                GridCacheEntryEx e = it.next();
                assert e != null;
                while (true) {
                    try {
                        // Don't return anything for invalid partitions.
                        if (tx == null || !tx.isRollbackOnly()) {
                            GridCacheVersion dhtVer = req.dhtVersion(i);
                            GridCacheVersion ver = e.version();
                            boolean ret = req.returnValue(i) || dhtVer == null || !dhtVer.equals(ver);
                            CacheObject val = null;
                            if (ret)
                                val = e.innerGet(null, tx, /*read-through*/
                                false, /*update-metrics*/
                                true, /*event notification*/
                                req.returnValue(i), CU.subjectId(tx, ctx.shared()), null, tx != null ? tx.resolveTaskName() : null, null, req.keepBinary());
                            assert e.lockedBy(mappedVer) || (ctx.mvcc().isRemoved(e.context(), mappedVer) && req.timeout() > 0) : "Entry does not own lock for tx [locNodeId=" + ctx.localNodeId() + ", entry=" + e + ", mappedVer=" + mappedVer + ", ver=" + ver + ", tx=" + tx + ", req=" + req + ", err=" + err + ']';
                            boolean filterPassed = false;
                            if (tx != null && tx.onePhaseCommit()) {
                                IgniteTxEntry writeEntry = tx.entry(ctx.txKey(e.key()));
                                assert writeEntry != null : "Missing tx entry for locked cache entry: " + e;
                                filterPassed = writeEntry.filtersPassed();
                            }
                            if (ret && val == null)
                                val = e.valueBytes(null);
                            // We include values into response since they are required for local
                            // calls and won't be serialized. We are also including DHT version.
                            res.addValueBytes(ret ? val : null, filterPassed, ver, mappedVer);
                        } else {
                            // We include values into response since they are required for local
                            // calls and won't be serialized. We are also including DHT version.
                            res.addValueBytes(null, false, e.version(), mappedVer);
                        }
                        break;
                    } catch (GridCacheEntryRemovedException ignore) {
                        if (log.isDebugEnabled())
                            log.debug("Got removed entry when sending reply to DHT lock request " + "(will retry): " + e);
                        e = entryExx(e.key());
                        it.set(e);
                    }
                }
                i++;
            }
        }
        return res;
    } catch (IgniteCheckedException e) {
        U.error(log, "Failed to get value for lock reply message for node [node=" + U.toShortString(nearNode) + ", req=" + req + ']', e);
        return new GridNearLockResponse(ctx.cacheId(), req.version(), req.futureId(), req.miniId(), false, entries.size(), e, null, ctx.deploymentEnabled());
    }
}
Also used : IgniteTxEntry(org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry) GridCacheEntryEx(org.apache.ignite.internal.processors.cache.GridCacheEntryEx) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) Collection(java.util.Collection) GridNearLockResponse(org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject)

Example 14 with GridCacheVersion

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

the class GridDhtLockFuture method loadMissingFromStore.

/**
     *
     */
private void loadMissingFromStore() {
    if (!skipStore && (read || cctx.loadPreviousValue()) && cctx.readThrough() && (needReturnVal || read)) {
        final Map<KeyCacheObject, GridDhtCacheEntry> loadMap = new LinkedHashMap<>();
        final GridCacheVersion ver = version();
        for (GridDhtCacheEntry entry : entries) {
            try {
                entry.unswap(false);
                if (!entry.hasValue())
                    loadMap.put(entry.key(), entry);
            } catch (GridCacheEntryRemovedException e) {
                assert false : "Should not get removed exception while holding lock on entry " + "[entry=" + entry + ", e=" + e + ']';
            } catch (IgniteCheckedException e) {
                onDone(e);
                return;
            }
        }
        try {
            cctx.store().loadAll(null, loadMap.keySet(), new CI2<KeyCacheObject, Object>() {

                @Override
                public void apply(KeyCacheObject key, Object val) {
                    // No value loaded from store.
                    if (val == null)
                        return;
                    GridDhtCacheEntry entry0 = loadMap.get(key);
                    try {
                        CacheObject val0 = cctx.toCacheObject(val);
                        long ttl = createTtl;
                        long expireTime;
                        if (ttl == CU.TTL_ZERO)
                            expireTime = CU.expireTimeInPast();
                        else {
                            if (ttl == CU.TTL_NOT_CHANGED)
                                ttl = CU.TTL_ETERNAL;
                            expireTime = CU.toExpireTime(ttl);
                        }
                        entry0.initialValue(val0, ver, ttl, expireTime, false, topVer, GridDrType.DR_LOAD, true);
                    } catch (GridCacheEntryRemovedException e) {
                        assert false : "Should not get removed exception while holding lock on entry " + "[entry=" + entry0 + ", e=" + e + ']';
                    } catch (IgniteCheckedException e) {
                        onDone(e);
                    }
                }
            });
        } catch (IgniteCheckedException e) {
            onDone(e);
        }
    }
}
Also used : GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) LinkedHashMap(java.util.LinkedHashMap) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject)

Example 15 with GridCacheVersion

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

the class GridDhtCacheEntry method localCandidateByNearVersion.

/**
     * @param nearVer Near version.
     * @param rmv If {@code true}, then add to removed list if not found.
     * @return Local candidate by near version.
     * @throws GridCacheEntryRemovedException If removed.
     */
@Nullable
synchronized GridCacheMvccCandidate localCandidateByNearVersion(GridCacheVersion nearVer, boolean rmv) throws GridCacheEntryRemovedException {
    checkObsolete();
    GridCacheMvcc mvcc = mvccExtras();
    if (mvcc != null) {
        for (GridCacheMvccCandidate c : mvcc.localCandidatesNoCopy(false)) {
            GridCacheVersion ver = c.otherVersion();
            if (ver != null && ver.equals(nearVer))
                return c;
        }
    }
    if (rmv)
        addRemoved(nearVer);
    return null;
}
Also used : GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) GridCacheMvcc(org.apache.ignite.internal.processors.cache.GridCacheMvcc) GridCacheMvccCandidate(org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

GridCacheVersion (org.apache.ignite.internal.processors.cache.version.GridCacheVersion)177 UUID (java.util.UUID)57 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)56 KeyCacheObject (org.apache.ignite.internal.processors.cache.KeyCacheObject)52 CacheObject (org.apache.ignite.internal.processors.cache.CacheObject)42 GridCacheEntryRemovedException (org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException)41 GridCacheEntryEx (org.apache.ignite.internal.processors.cache.GridCacheEntryEx)22 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)20 ClusterNode (org.apache.ignite.cluster.ClusterNode)19 Map (java.util.Map)17 ClusterTopologyCheckedException (org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)16 ArrayList (java.util.ArrayList)14 GridCacheMvccCandidate (org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate)14 IgniteTxKey (org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey)14 IgniteTxEntry (org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry)13 GridCacheContext (org.apache.ignite.internal.processors.cache.GridCacheContext)12 IgniteException (org.apache.ignite.IgniteException)11 IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)11 GridDhtInvalidPartitionException (org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException)11 HashMap (java.util.HashMap)10