Search in sources :

Example 91 with IgniteInternalFuture

use of org.apache.ignite.internal.IgniteInternalFuture in project ignite by apache.

the class CacheExchangeMergeTest method startGridsAsync.

/**
 * Sequentially starts nodes so that node name is consistent with node order.
 *
 * @param node Some existing node.
 * @param startIdx Start node index.
 * @param cnt Number of nodes.
 * @return Start future.
 * @throws Exception If failed.
 */
private IgniteInternalFuture startGridsAsync(Ignite node, int startIdx, int cnt) throws Exception {
    GridCompoundFuture fut = new GridCompoundFuture();
    for (int i = 0; i < cnt; i++) {
        final CountDownLatch latch = new CountDownLatch(1);
        node.events().localListen(new IgnitePredicate<Event>() {

            @Override
            public boolean apply(Event evt) {
                log.info("Got event: " + ((DiscoveryEvent) evt).eventNode().id());
                latch.countDown();
                return false;
            }
        }, EventType.EVT_NODE_JOINED);
        final int nodeIdx = startIdx + i;
        IgniteInternalFuture fut0 = GridTestUtils.runAsync(new Callable() {

            @Override
            public Object call() throws Exception {
                log.info("Start new node: " + nodeIdx);
                startGrid(nodeIdx);
                return null;
            }
        }, "start-node-" + nodeIdx);
        if (!latch.await(WAIT_SECONDS, TimeUnit.SECONDS))
            fail();
        fut.add(fut0);
    }
    fut.markInitialized();
    return fut;
}
Also used : Event(org.apache.ignite.events.Event) DiscoveryEvent(org.apache.ignite.events.DiscoveryEvent) DiscoveryEvent(org.apache.ignite.events.DiscoveryEvent) CountDownLatch(java.util.concurrent.CountDownLatch) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) GridCompoundFuture(org.apache.ignite.internal.util.future.GridCompoundFuture) Callable(java.util.concurrent.Callable) ClusterTopologyException(org.apache.ignite.cluster.ClusterTopologyException)

Example 92 with IgniteInternalFuture

use of org.apache.ignite.internal.IgniteInternalFuture in project ignite by apache.

the class IgniteTxHandler method prepareNearTx.

/**
 * @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 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);
    }
    assert firstEntry != null : req;
    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 req.concurrency() == OPTIMISTIC : req;
            assert CU.clientNode(nearNode) : 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(), req.subjectId(), req.taskNameHash());
            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.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 93 with IgniteInternalFuture

use of org.apache.ignite.internal.IgniteInternalFuture in project ignite by apache.

the class IgniteTxHandler method finishDhtLocal.

/**
 * @param nodeId Node ID initiated commit.
 * @param locTx Optional local transaction.
 * @param req Finish request.
 * @return Finish future.
 */
private IgniteInternalFuture<IgniteInternalTx> finishDhtLocal(UUID nodeId, @Nullable GridNearTxLocal locTx, GridNearTxFinishRequest req) {
    GridCacheVersion dhtVer = ctx.tm().mappedVersion(req.version());
    GridDhtTxLocal tx = null;
    if (dhtVer == null) {
        if (log.isDebugEnabled())
            log.debug("Received transaction finish request for unknown near version (was lock explicit?): " + req);
    } else
        tx = ctx.tm().tx(dhtVer);
    if (tx != null)
        req.txState(tx.txState());
    if (tx == null && locTx != null && !req.commit()) {
        U.warn(log, "DHT local tx not found for near local tx rollback " + "[req=" + req + ", dhtVer=" + dhtVer + ", tx=" + locTx + ']');
        return null;
    }
    if (tx == null && !req.explicitLock()) {
        assert locTx == null : "DHT local tx should never be lost for near local tx: " + locTx;
        U.warn(txFinishMsgLog, "Received finish request for completed transaction (the message may be too late) [" + "txId=" + req.version() + ", dhtTxId=" + dhtVer + ", node=" + nodeId + ", commit=" + req.commit() + ']');
        // Always send finish response.
        GridCacheMessage res = new GridNearTxFinishResponse(req.partition(), req.version(), req.threadId(), req.futureId(), req.miniId(), new IgniteCheckedException("Transaction has been already completed."));
        try {
            ctx.io().send(nodeId, res, req.policy());
            if (txFinishMsgLog.isDebugEnabled()) {
                txFinishMsgLog.debug("Sent near finish response for completed tx [txId=" + req.version() + ", dhtTxId=" + dhtVer + ", node=" + nodeId + ']');
            }
        } catch (Throwable e) {
            // Double-check.
            if (ctx.discovery().node(nodeId) == null) {
                if (txFinishMsgLog.isDebugEnabled()) {
                    txFinishMsgLog.debug("Failed to send near finish response for completed tx, node failed [" + "txId=" + req.version() + ", dhtTxId=" + dhtVer + ", node=" + nodeId + ']');
                }
            } else {
                U.error(txFinishMsgLog, "Failed to send near finish response for completed tx, node failed [" + "txId=" + req.version() + ", dhtTxId=" + dhtVer + ", node=" + nodeId + ", req=" + req + ", res=" + res + ']', e);
            }
            if (e instanceof Error)
                throw (Error) e;
        }
        return null;
    }
    try {
        assert tx != null : "Transaction is null for near finish request [nodeId=" + nodeId + ", req=" + req + "]";
        assert req.syncMode() != null : req;
        tx.syncMode(req.syncMode());
        tx.nearFinishFutureId(req.futureId());
        tx.nearFinishMiniId(req.miniId());
        tx.storeEnabled(req.storeEnabled());
        if (req.commit()) {
            if (!tx.markFinalizing(USER_FINISH)) {
                if (log.isDebugEnabled())
                    log.debug("Will not finish transaction (it is handled by another thread): " + tx);
                return null;
            }
            IgniteInternalFuture<IgniteInternalTx> commitFut = tx.commitDhtLocalAsync();
            // Only for error logging.
            commitFut.listen(CU.errorLogger(log));
            return commitFut;
        } else {
            IgniteInternalFuture<IgniteInternalTx> rollbackFut = tx.rollbackDhtLocalAsync();
            // Only for error logging.
            rollbackFut.listen(CU.errorLogger(log));
            return rollbackFut;
        }
    } catch (Throwable e) {
        U.error(log, "Failed completing transaction [commit=" + req.commit() + ", tx=" + tx + ']', e);
        if (tx != null) {
            tx.commitError(e);
            tx.systemInvalidate(true);
            try {
                IgniteInternalFuture<IgniteInternalTx> res = tx.rollbackDhtLocalAsync();
                // Only for error logging.
                res.listen(CU.errorLogger(log));
                return res;
            } catch (Throwable e1) {
                e.addSuppressed(e1);
            }
        }
        if (e instanceof Error)
            throw (Error) e;
        return new GridFinishedFuture<>(e);
    }
}
Also used : GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridDhtTxLocal(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxLocal) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) GridCacheMessage(org.apache.ignite.internal.processors.cache.GridCacheMessage) GridNearTxFinishResponse(org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxFinishResponse)

Example 94 with IgniteInternalFuture

use of org.apache.ignite.internal.IgniteInternalFuture in project ignite by apache.

the class IgniteTxHandler method processDhtTxPrepareRequest.

/**
 * @param nodeId Sender node ID.
 * @param req Request.
 */
private void processDhtTxPrepareRequest(final UUID nodeId, final GridDhtTxPrepareRequest req) {
    if (txPrepareMsgLog.isDebugEnabled()) {
        txPrepareMsgLog.debug("Received dht prepare request [txId=" + req.nearXidVersion() + ", dhtTxId=" + req.version() + ", node=" + nodeId + ']');
    }
    assert nodeId != null;
    assert req != null;
    assert req.transactionNodes() != null;
    GridDhtTxRemote dhtTx = null;
    GridNearTxRemote nearTx = null;
    GridDhtTxPrepareResponse res;
    try {
        res = new GridDhtTxPrepareResponse(req.partition(), req.version(), req.futureId(), req.miniId(), req.deployInfo() != null);
        // Start near transaction first.
        nearTx = !F.isEmpty(req.nearWrites()) ? startNearRemoteTx(ctx.deploy().globalLoader(), nodeId, req) : null;
        dhtTx = startRemoteTx(nodeId, req, res);
        // Set evicted keys from near transaction.
        if (nearTx != null)
            res.nearEvicted(nearTx.evicted());
        List<IgniteTxKey> writesCacheMissed = req.nearWritesCacheMissed();
        if (writesCacheMissed != null) {
            Collection<IgniteTxKey> evicted0 = res.nearEvicted();
            if (evicted0 != null)
                writesCacheMissed.addAll(evicted0);
            res.nearEvicted(writesCacheMissed);
        }
        if (dhtTx != null)
            req.txState(dhtTx.txState());
        else if (nearTx != null)
            req.txState(nearTx.txState());
        if (dhtTx != null && !F.isEmpty(dhtTx.invalidPartitions()))
            res.invalidPartitionsByCacheId(dhtTx.invalidPartitions());
        if (req.onePhaseCommit()) {
            assert req.last();
            if (dhtTx != null) {
                dhtTx.onePhaseCommit(true);
                dhtTx.needReturnValue(req.needReturnValue());
                finish(dhtTx, req);
            }
            if (nearTx != null) {
                nearTx.onePhaseCommit(true);
                finish(nearTx, req);
            }
        }
    } catch (IgniteCheckedException e) {
        if (e instanceof IgniteTxRollbackCheckedException)
            U.error(log, "Transaction was rolled back before prepare completed: " + req, e);
        else if (e instanceof IgniteTxOptimisticCheckedException) {
            if (log.isDebugEnabled())
                log.debug("Optimistic failure for remote transaction (will rollback): " + req);
        } else if (e instanceof IgniteTxHeuristicCheckedException) {
            U.warn(log, "Failed to commit transaction (all transaction entries were invalidated): " + CU.txString(dhtTx));
        } else
            U.error(log, "Failed to process prepare request: " + req, e);
        if (nearTx != null)
            try {
                nearTx.rollbackRemoteTx();
            } catch (Throwable e1) {
                e.addSuppressed(e1);
            }
        res = new GridDhtTxPrepareResponse(req.partition(), req.version(), req.futureId(), req.miniId(), e, req.deployInfo() != null);
    }
    if (req.onePhaseCommit()) {
        IgniteInternalFuture completeFut;
        IgniteInternalFuture<IgniteInternalTx> dhtFin = dhtTx == null ? null : dhtTx.done() ? null : dhtTx.finishFuture();
        final IgniteInternalFuture<IgniteInternalTx> nearFin = nearTx == null ? null : nearTx.done() ? null : nearTx.finishFuture();
        if (dhtFin != null && nearFin != null) {
            GridCompoundFuture fut = new GridCompoundFuture();
            fut.add(dhtFin);
            fut.add(nearFin);
            fut.markInitialized();
            completeFut = fut;
        } else
            completeFut = dhtFin != null ? dhtFin : nearFin;
        if (completeFut != null) {
            final GridDhtTxPrepareResponse res0 = res;
            final GridDhtTxRemote dhtTx0 = dhtTx;
            final GridNearTxRemote nearTx0 = nearTx;
            completeFut.listen(new CI1<IgniteInternalFuture<IgniteInternalTx>>() {

                @Override
                public void apply(IgniteInternalFuture<IgniteInternalTx> fut) {
                    sendReply(nodeId, req, res0, dhtTx0, nearTx0);
                }
            });
        } else
            sendReply(nodeId, req, res, dhtTx, nearTx);
    } else
        sendReply(nodeId, req, res, dhtTx, nearTx);
    assert req.txState() != null || res.error() != null || (dhtTx == null && nearTx == null) : req + " tx=" + dhtTx + " nearTx=" + nearTx;
}
Also used : GridDhtTxRemote(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxRemote) IgniteTxRollbackCheckedException(org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException) GridDhtTxPrepareResponse(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxPrepareResponse) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) IgniteTxHeuristicCheckedException(org.apache.ignite.internal.transactions.IgniteTxHeuristicCheckedException) GridNearTxRemote(org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxRemote) IgniteTxOptimisticCheckedException(org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException) GridCompoundFuture(org.apache.ignite.internal.util.future.GridCompoundFuture) IgniteCheckedException(org.apache.ignite.IgniteCheckedException)

Example 95 with IgniteInternalFuture

use of org.apache.ignite.internal.IgniteInternalFuture in project ignite by apache.

the class GridPartitionedSingleGetFuture method onNodeLeft.

/**
 * {@inheritDoc}
 */
@Override
public boolean onNodeLeft(UUID nodeId) {
    if (!processResponse(nodeId))
        return false;
    if (canRemap) {
        AffinityTopologyVersion updTopVer = new AffinityTopologyVersion(Math.max(topVer.topologyVersion() + 1, cctx.discovery().topologyVersion()));
        cctx.affinity().affinityReadyFuture(updTopVer).listen(new CI1<IgniteInternalFuture<AffinityTopologyVersion>>() {

            @Override
            public void apply(IgniteInternalFuture<AffinityTopologyVersion> fut) {
                try {
                    remap(fut.get());
                } catch (IgniteCheckedException e) {
                    onDone(e);
                }
            }
        });
    } else
        remap(topVer);
    return true;
}
Also used : IgniteCheckedException(org.apache.ignite.IgniteCheckedException) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture)

Aggregations

IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)245 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)114 Ignite (org.apache.ignite.Ignite)71 ArrayList (java.util.ArrayList)52 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)46 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)46 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)43 IgniteException (org.apache.ignite.IgniteException)33 ClusterTopologyCheckedException (org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)29 UUID (java.util.UUID)28 IgniteCache (org.apache.ignite.IgniteCache)28 ClusterNode (org.apache.ignite.cluster.ClusterNode)28 Callable (java.util.concurrent.Callable)27 HashMap (java.util.HashMap)25 Map (java.util.Map)25 CountDownLatch (java.util.concurrent.CountDownLatch)24 CacheConfiguration (org.apache.ignite.configuration.CacheConfiguration)19 CacheException (javax.cache.CacheException)16 GridFinishedFuture (org.apache.ignite.internal.util.future.GridFinishedFuture)16 GridFutureAdapter (org.apache.ignite.internal.util.future.GridFutureAdapter)16