Search in sources :

Example 11 with GridDhtTopologyFuture

use of org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture in project ignite by apache.

the class GridNearLockFuture method mapOnTopology.

/**
 * Acquires topology future and checks it completeness under the read lock. If it is not complete,
 * will asynchronously wait for it's completeness and then try again.
 *
 * @param remap Remap flag.
 */
synchronized void mapOnTopology(final boolean remap) {
    // We must acquire topology snapshot from the topology version future.
    cctx.topology().readLock();
    try {
        if (cctx.topology().stopping()) {
            onDone(cctx.shared().cache().isCacheRestarting(cctx.name()) ? new IgniteCacheRestartingException(cctx.name()) : new CacheStoppedException(cctx.name()));
            return;
        }
        GridDhtTopologyFuture fut = cctx.topologyVersionFuture();
        if (fut.isDone()) {
            Throwable err = fut.validateCache(cctx, recovery, read, null, keys);
            if (err != null) {
                onDone(err);
                return;
            }
            AffinityTopologyVersion topVer = fut.topologyVersion();
            if (remap) {
                if (tx != null)
                    tx.onRemap(topVer, true);
                this.topVer = topVer;
            } else {
                if (tx != null)
                    tx.topologyVersion(topVer);
                if (this.topVer == null)
                    this.topVer = topVer;
            }
            map(keys, remap, false);
            markInitialized();
        } else {
            fut.listen(new CI1<IgniteInternalFuture<AffinityTopologyVersion>>() {

                @Override
                public void apply(IgniteInternalFuture<AffinityTopologyVersion> fut) {
                    try {
                        fut.get();
                        mapOnTopology(remap);
                    } catch (IgniteCheckedException e) {
                        onDone(e);
                    } finally {
                        cctx.shared().txContextReset();
                    }
                }
            });
        }
    } finally {
        cctx.topology().readUnlock();
    }
}
Also used : GridDhtTopologyFuture(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) CacheStoppedException(org.apache.ignite.internal.processors.cache.CacheStoppedException) IgniteCacheRestartingException(org.apache.ignite.IgniteCacheRestartingException) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture)

Example 12 with GridDhtTopologyFuture

use of org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture in project ignite by apache.

the class GridNearOptimisticTxPrepareFutureAdapter method prepareOnTopology.

/**
 * @param remap Remap flag.
 * @param c Optional closure to run after map.
 */
protected final void prepareOnTopology(final boolean remap, @Nullable final Runnable c) {
    GridDhtTopologyFuture topFut = topologyReadLock();
    AffinityTopologyVersion topVer = null;
    try {
        if (topFut == null) {
            assert isDone();
            return;
        }
        if (topFut.isDone()) {
            if ((topVer = topFut.topologyVersion()) == null && topFut.error() != null) {
                // Prevent stack overflow if topFut has error.
                onDone(topFut.error());
                return;
            }
            if (remap)
                tx.onRemap(topVer, true);
            else
                tx.topologyVersion(topVer);
            if (!remap)
                cctx.mvcc().addFuture(this);
        }
    } finally {
        topologyReadUnlock();
    }
    if (topVer != null) {
        IgniteCheckedException err = tx.txState().validateTopology(cctx, tx.writeMap().isEmpty(), topFut);
        if (err != null) {
            onDone(err);
            return;
        }
        if (tx.isRollbackOnly()) {
            onDone(new IgniteTxRollbackCheckedException("Failed to prepare the transaction, due to the transaction is marked as rolled back " + "[tx=" + CU.txString(tx) + ']'));
            return;
        }
        prepare0(remap, false);
        if (c != null)
            c.run();
    } else {
        cctx.time().waitAsync(topFut, tx.remainingTime(), (e, timedOut) -> {
            if (errorOrTimeoutOnTopologyVersion(e, timedOut))
                return;
            try {
                if (tx.isRollbackOnly()) {
                    onDone(new IgniteTxRollbackCheckedException("Failed to prepare the transaction, due to the transaction is marked as rolled back " + "[tx=" + CU.txString(tx) + ']'));
                    return;
                }
                prepareOnTopology(remap, c);
            } finally {
                cctx.txContextReset();
            }
        });
    }
}
Also used : GridDhtTopologyFuture(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) IgniteTxRollbackCheckedException(org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException)

Example 13 with GridDhtTopologyFuture

use of org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture in project ignite by apache.

the class GridNearTxAbstractEnlistFuture method mapOnTopology.

/**
 */
private void mapOnTopology() {
    cctx.topology().readLock();
    boolean topLocked = true;
    try {
        if (cctx.topology().stopping()) {
            onDone(cctx.shared().cache().isCacheRestarting(cctx.name()) ? new IgniteCacheRestartingException(cctx.name()) : new CacheStoppedException(cctx.name()));
            return;
        }
        GridDhtTopologyFuture fut = cctx.topologyVersionFuture();
        cctx.topology().readUnlock();
        topLocked = false;
        if (fut.isDone()) {
            Throwable err = fut.validateCache(cctx, false, false, null, null);
            if (err != null) {
                onDone(err);
                return;
            }
            AffinityTopologyVersion topVer = fut.topologyVersion();
            tx.topologyVersion(topVer);
            if (this.topVer == null)
                this.topVer = topVer;
            map(false);
        } else {
            cctx.time().waitAsync(fut, tx.remainingTime(), (e, timedOut) -> {
                try {
                    if (e != null || timedOut)
                        onDone(timedOut ? tx.timeoutException() : e);
                    else
                        mapOnTopology();
                } finally {
                    cctx.shared().txContextReset();
                }
            });
        }
    } finally {
        if (topLocked)
            cctx.topology().readUnlock();
    }
}
Also used : GridDhtTopologyFuture(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture) CacheStoppedException(org.apache.ignite.internal.processors.cache.CacheStoppedException) IgniteCacheRestartingException(org.apache.ignite.IgniteCacheRestartingException) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)

Example 14 with GridDhtTopologyFuture

use of org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture in project ignite by apache.

the class IgniteTxHandler method prepareNearTx.

/**
 * @param originTx Transaction for copy.
 * @param nearNode Node that initiated transaction.
 * @param req Near prepare request.
 * @return Prepare future or {@code null} if need retry operation.
 */
@Nullable
private IgniteInternalFuture<GridNearTxPrepareResponse> prepareNearTx(final GridNearTxLocal originTx, final ClusterNode nearNode, final GridNearTxPrepareRequest req) {
    IgniteTxEntry firstEntry;
    try {
        IgniteTxEntry firstWrite = unmarshal(req.writes());
        IgniteTxEntry firstRead = unmarshal(req.reads());
        firstEntry = firstWrite != null ? firstWrite : firstRead;
    } catch (IgniteCheckedException e) {
        return new GridFinishedFuture<>(e);
    }
    GridDhtTxLocal tx = null;
    GridCacheVersion mappedVer = ctx.tm().mappedVersion(req.version());
    if (mappedVer != null) {
        tx = ctx.tm().tx(mappedVer);
        if (tx == null)
            U.warn(log, "Missing local transaction for mapped near version [nearVer=" + req.version() + ", mappedVer=" + mappedVer + ']');
        else {
            if (req.concurrency() == PESSIMISTIC)
                tx.nearFutureId(req.futureId());
        }
    } else {
        GridDhtPartitionTopology top = null;
        if (req.firstClientRequest()) {
            assert firstEntry != null : req;
            assert req.concurrency() == OPTIMISTIC : req;
            assert nearNode.isClient() : nearNode;
            top = firstEntry.context().topology();
            top.readLock();
            if (req.allowWaitTopologyFuture()) {
                GridDhtTopologyFuture topFut = top.topologyVersionFuture();
                if (!topFut.isDone()) {
                    top.readUnlock();
                    return null;
                }
            }
        }
        try {
            if (top != null) {
                boolean retry = false;
                GridDhtTopologyFuture topFut = top.topologyVersionFuture();
                if (!req.allowWaitTopologyFuture() && !topFut.isDone()) {
                    retry = true;
                    if (txPrepareMsgLog.isDebugEnabled()) {
                        txPrepareMsgLog.debug("Topology change is in progress, need remap transaction [" + "txId=" + req.version() + ", node=" + nearNode.id() + ", reqTopVer=" + req.topologyVersion() + ", locTopVer=" + top.readyTopologyVersion() + ", req=" + req + ']');
                    }
                }
                if (!retry && needRemap(req.topologyVersion(), top.readyTopologyVersion(), req)) {
                    retry = true;
                    if (txPrepareMsgLog.isDebugEnabled()) {
                        txPrepareMsgLog.debug("Topology version mismatch for near prepare, need remap transaction [" + "txId=" + req.version() + ", node=" + nearNode.id() + ", reqTopVer=" + req.topologyVersion() + ", locTopVer=" + top.readyTopologyVersion() + ", req=" + req + ']');
                    }
                }
                if (retry) {
                    GridNearTxPrepareResponse res = new GridNearTxPrepareResponse(req.partition(), req.version(), req.futureId(), req.miniId(), req.version(), req.version(), null, null, top.lastTopologyChangeVersion(), req.onePhaseCommit(), req.deployInfo() != null);
                    try {
                        ctx.io().send(nearNode, res, req.policy());
                        if (txPrepareMsgLog.isDebugEnabled()) {
                            txPrepareMsgLog.debug("Sent remap response for near prepare [txId=" + req.version() + ", node=" + nearNode.id() + ']');
                        }
                    } catch (ClusterTopologyCheckedException ignored) {
                        if (txPrepareMsgLog.isDebugEnabled()) {
                            txPrepareMsgLog.debug("Failed to send remap response for near prepare, node failed [" + "txId=" + req.version() + ", node=" + nearNode.id() + ']');
                        }
                    } catch (IgniteCheckedException e) {
                        U.error(txPrepareMsgLog, "Failed to send remap response for near prepare " + "[txId=" + req.version() + ", node=" + nearNode.id() + ", req=" + req + ']', e);
                    }
                    return new GridFinishedFuture<>(res);
                }
                assert topFut.isDone();
            }
            tx = new GridDhtTxLocal(ctx, req.topologyVersion(), nearNode.id(), req.version(), req.futureId(), req.miniId(), req.threadId(), req.implicitSingle(), req.implicitSingle(), req.system(), req.explicitLock(), req.policy(), req.concurrency(), req.isolation(), req.timeout(), req.isInvalidate(), true, req.onePhaseCommit(), req.txSize(), req.transactionNodes(), securitySubjectId(ctx), req.taskNameHash(), req.txLabel(), originTx);
            tx = ctx.tm().onCreated(null, tx);
            if (tx != null)
                tx.topologyVersion(req.topologyVersion());
            else
                U.warn(log, "Failed to create local transaction (was transaction rolled back?) [xid=" + req.version() + ", req=" + req + ']');
        } finally {
            if (tx != null)
                req.txState(tx.txState());
            if (top != null)
                top.readUnlock();
        }
    }
    if (tx != null) {
        req.txState(tx.txState());
        if (req.explicitLock())
            tx.explicitLock(true);
        tx.transactionNodes(req.transactionNodes());
        if (req.near())
            tx.nearOnOriginatingNode(true);
        if (req.onePhaseCommit()) {
            assert req.last() : req;
            tx.onePhaseCommit(true);
        }
        if (req.needReturnValue())
            tx.needReturnValue(true);
        IgniteInternalFuture<GridNearTxPrepareResponse> fut = tx.prepareAsync(req);
        if (tx.isRollbackOnly() && !tx.commitOnPrepare()) {
            if (tx.state() != TransactionState.ROLLED_BACK && tx.state() != TransactionState.ROLLING_BACK)
                tx.rollbackDhtLocalAsync();
        }
        final GridDhtTxLocal tx0 = tx;
        fut.listen(new CI1<IgniteInternalFuture<?>>() {

            @Override
            public void apply(IgniteInternalFuture<?> txFut) {
                try {
                    txFut.get();
                } catch (IgniteCheckedException e) {
                    // Just in case.
                    tx0.setRollbackOnly();
                    if (!X.hasCause(e, IgniteTxOptimisticCheckedException.class) && !X.hasCause(e, IgniteFutureCancelledException.class) && !ctx.kernalContext().isStopping())
                        U.error(log, "Failed to prepare DHT transaction: " + tx0, e);
                }
            }
        });
        return fut;
    } else
        return new GridFinishedFuture<>((GridNearTxPrepareResponse) null);
}
Also used : GridDhtTxLocal(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxLocal) GridDhtPartitionTopology(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionTopology) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) IgniteTxOptimisticCheckedException(org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException) GridFinishedFuture(org.apache.ignite.internal.util.future.GridFinishedFuture) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) GridDhtTopologyFuture(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridNearTxPrepareResponse(org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxPrepareResponse) IgniteFutureCancelledException(org.apache.ignite.lang.IgniteFutureCancelledException) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException) Nullable(org.jetbrains.annotations.Nullable)

Example 15 with GridDhtTopologyFuture

use of org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture in project ignite by apache.

the class DataStreamProcessor method localUpdate.

/**
 * @param nodeId Node id.
 * @param req Request.
 * @param updater Updater.
 * @param topic Topic.
 */
private void localUpdate(final UUID nodeId, final DataStreamerRequest req, final StreamReceiver<K, V> updater, final Object topic) {
    final boolean allowOverwrite = !(updater instanceof DataStreamerImpl.IsolatedUpdater);
    try {
        GridCacheAdapter cache = ctx.cache().internalCache(req.cacheName());
        if (cache == null) {
            throw new IgniteCheckedException("Cache not created or already destroyed: " + req.cacheName());
        }
        GridCacheContext cctx = cache.context();
        DataStreamerUpdateJob job = null;
        GridFutureAdapter waitFut = null;
        if (!allowOverwrite)
            cctx.topology().readLock();
        GridDhtTopologyFuture topWaitFut = null;
        try {
            Exception remapErr = null;
            AffinityTopologyVersion streamerFutTopVer = null;
            if (!allowOverwrite) {
                GridDhtTopologyFuture topFut = cctx.topologyVersionFuture();
                AffinityTopologyVersion topVer = topFut.isDone() ? topFut.topologyVersion() : topFut.initialVersion();
                if (topVer.compareTo(req.topologyVersion()) > 0) {
                    remapErr = new ClusterTopologyCheckedException("DataStreamer will retry " + "data transfer at stable topology [reqTop=" + req.topologyVersion() + ", topVer=" + topFut.initialVersion() + ", node=remote]");
                } else if (!topFut.isDone())
                    topWaitFut = topFut;
                else
                    streamerFutTopVer = topFut.topologyVersion();
            }
            if (remapErr != null) {
                sendResponse(nodeId, topic, req.requestId(), remapErr, req.forceLocalDeployment());
                return;
            } else if (topWaitFut == null) {
                job = new DataStreamerUpdateJob(ctx, log, req.cacheName(), req.entries(), req.ignoreDeploymentOwnership(), req.skipStore(), req.keepBinary(), updater);
                waitFut = allowOverwrite ? null : cctx.mvcc().addDataStreamerFuture(streamerFutTopVer);
            }
        } finally {
            if (!allowOverwrite)
                cctx.topology().readUnlock();
        }
        if (topWaitFut != null) {
            // Need call 'listen' after topology read lock is released.
            topWaitFut.listen(new IgniteInClosure<IgniteInternalFuture<AffinityTopologyVersion>>() {

                @Override
                public void apply(IgniteInternalFuture<AffinityTopologyVersion> e) {
                    localUpdate(nodeId, req, updater, topic);
                }
            });
            return;
        }
        try {
            job.call();
            sendResponse(nodeId, topic, req.requestId(), null, req.forceLocalDeployment());
        } finally {
            if (waitFut != null)
                waitFut.onDone();
        }
    } catch (Throwable e) {
        sendResponse(nodeId, topic, req.requestId(), e, req.forceLocalDeployment());
        if (e instanceof Error)
            throw (Error) e;
    }
}
Also used : GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) IgniteInterruptedCheckedException(org.apache.ignite.internal.IgniteInterruptedCheckedException) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException) GridDhtTopologyFuture(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridCacheAdapter(org.apache.ignite.internal.processors.cache.GridCacheAdapter) GridFutureAdapter(org.apache.ignite.internal.util.future.GridFutureAdapter) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)

Aggregations

GridDhtTopologyFuture (org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture)18 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)14 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)10 IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)10 Map (java.util.Map)5 Ignite (org.apache.ignite.Ignite)5 IgniteCacheRestartingException (org.apache.ignite.IgniteCacheRestartingException)5 ClusterTopologyCheckedException (org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)5 CacheStoppedException (org.apache.ignite.internal.processors.cache.CacheStoppedException)5 HashSet (java.util.HashSet)4 IgniteException (org.apache.ignite.IgniteException)4 GridFinishedFuture (org.apache.ignite.internal.util.future.GridFinishedFuture)4 ClusterNode (org.apache.ignite.cluster.ClusterNode)3 ClusterTopologyException (org.apache.ignite.cluster.ClusterTopologyException)3 CacheConfiguration (org.apache.ignite.configuration.CacheConfiguration)3 IOException (java.io.IOException)2 InvalidObjectException (java.io.InvalidObjectException)2 ObjectStreamException (java.io.ObjectStreamException)2 Collection (java.util.Collection)2 HashMap (java.util.HashMap)2