Search in sources :

Example 6 with ClusterTopologyCheckedException

use of org.apache.ignite.internal.cluster.ClusterTopologyCheckedException 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 7 with ClusterTopologyCheckedException

use of org.apache.ignite.internal.cluster.ClusterTopologyCheckedException in project ignite by apache.

the class GridDhtPartitionDemander method handleSupplyMessage.

/**
 * Handles supply message from {@code nodeId} with specified {@code topicId}.
 *
 * Supply message contains entries to populate rebalancing partitions.
 *
 * There is a cyclic process:
 * Populate rebalancing partitions with entries from Supply message.
 * If not all partitions specified in {@link #rebalanceFut} were rebalanced or marked as missed
 * send new Demand message to request next batch of entries.
 *
 * @param topicId Topic id.
 * @param nodeId Node id.
 * @param supply Supply message.
 */
public void handleSupplyMessage(int topicId, final UUID nodeId, final GridDhtPartitionSupplyMessage supply) {
    AffinityTopologyVersion topVer = supply.topologyVersion();
    final RebalanceFuture fut = rebalanceFut;
    ClusterNode node = ctx.node(nodeId);
    if (node == null)
        return;
    if (// Topology already changed (for the future that supply message based on).
    topologyChanged(fut))
        return;
    if (!fut.isActual(supply.rebalanceId())) {
        // Supple message based on another future.
        return;
    }
    if (log.isDebugEnabled())
        log.debug("Received supply message [grp=" + grp.cacheOrGroupName() + ", msg=" + supply + ']');
    // Check whether there were class loading errors on unmarshal
    if (supply.classError() != null) {
        U.warn(log, "Rebalancing from node cancelled [grp=" + grp.cacheOrGroupName() + ", node=" + nodeId + "]. Class got undeployed during preloading: " + supply.classError());
        fut.cancel(nodeId);
        return;
    }
    final GridDhtPartitionTopology top = grp.topology();
    if (grp.sharedGroup()) {
        for (GridCacheContext cctx : grp.caches()) {
            if (cctx.statisticsEnabled()) {
                long keysCnt = supply.keysForCache(cctx.cacheId());
                if (keysCnt != -1)
                    cctx.cache().metrics0().onRebalancingKeysCountEstimateReceived(keysCnt);
                // Can not be calculated per cache.
                cctx.cache().metrics0().onRebalanceBatchReceived(supply.messageSize());
            }
        }
    } else {
        GridCacheContext cctx = grp.singleCacheContext();
        if (cctx.statisticsEnabled()) {
            if (supply.estimatedKeysCount() != -1)
                cctx.cache().metrics0().onRebalancingKeysCountEstimateReceived(supply.estimatedKeysCount());
            cctx.cache().metrics0().onRebalanceBatchReceived(supply.messageSize());
        }
    }
    try {
        AffinityAssignment aff = grp.affinity().cachedAffinity(topVer);
        GridCacheContext cctx = grp.sharedGroup() ? null : grp.singleCacheContext();
        // Preload.
        for (Map.Entry<Integer, CacheEntryInfoCollection> e : supply.infos().entrySet()) {
            int p = e.getKey();
            if (aff.get(p).contains(ctx.localNode())) {
                GridDhtLocalPartition part = top.localPartition(p, topVer, true);
                assert part != null;
                boolean last = supply.last().containsKey(p);
                if (part.state() == MOVING) {
                    boolean reserved = part.reserve();
                    assert reserved : "Failed to reserve partition [igniteInstanceName=" + ctx.igniteInstanceName() + ", grp=" + grp.cacheOrGroupName() + ", part=" + part + ']';
                    part.lock();
                    try {
                        // Loop through all received entries and try to preload them.
                        for (GridCacheEntryInfo entry : e.getValue().infos()) {
                            if (!preloadEntry(node, p, entry, topVer)) {
                                if (log.isDebugEnabled())
                                    log.debug("Got entries for invalid partition during " + "preloading (will skip) [p=" + p + ", entry=" + entry + ']');
                                break;
                            }
                            if (grp.sharedGroup() && (cctx == null || cctx.cacheId() != entry.cacheId()))
                                cctx = ctx.cacheContext(entry.cacheId());
                            if (cctx != null && cctx.statisticsEnabled())
                                cctx.cache().metrics0().onRebalanceKeyReceived();
                        }
                        // then we take ownership.
                        if (last) {
                            top.own(part);
                            fut.partitionDone(nodeId, p);
                            if (log.isDebugEnabled())
                                log.debug("Finished rebalancing partition: " + part);
                        }
                    } finally {
                        part.unlock();
                        part.release();
                    }
                } else {
                    if (last)
                        fut.partitionDone(nodeId, p);
                    if (log.isDebugEnabled())
                        log.debug("Skipping rebalancing partition (state is not MOVING): " + part);
                }
            } else {
                fut.partitionDone(nodeId, p);
                if (log.isDebugEnabled())
                    log.debug("Skipping rebalancing partition (it does not belong on current node): " + p);
            }
        }
        // Only request partitions based on latest topology version.
        for (Integer miss : supply.missed()) {
            if (aff.get(miss).contains(ctx.localNode()))
                fut.partitionMissed(nodeId, miss);
        }
        for (Integer miss : supply.missed()) fut.partitionDone(nodeId, miss);
        GridDhtPartitionDemandMessage d = new GridDhtPartitionDemandMessage(supply.rebalanceId(), supply.topologyVersion(), grp.groupId());
        d.timeout(grp.config().getRebalanceTimeout());
        d.topic(rebalanceTopics.get(topicId));
        if (!topologyChanged(fut) && !fut.isDone()) {
            // Send demand message.
            try {
                ctx.io().sendOrderedMessage(node, rebalanceTopics.get(topicId), d.convertIfNeeded(node.version()), grp.ioPolicy(), grp.config().getRebalanceTimeout());
            } catch (ClusterTopologyCheckedException e) {
                if (log.isDebugEnabled()) {
                    log.debug("Node left during rebalancing [grp=" + grp.cacheOrGroupName() + ", node=" + node.id() + ", msg=" + e.getMessage() + ']');
                }
            }
        }
    } catch (IgniteSpiException | IgniteCheckedException e) {
        LT.error(log, e, "Error during rebalancing [grp=" + grp.cacheOrGroupName() + ", srcNode=" + node.id() + ", err=" + e + ']');
    }
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) GridCacheEntryInfo(org.apache.ignite.internal.processors.cache.GridCacheEntryInfo) AffinityAssignment(org.apache.ignite.internal.processors.affinity.AffinityAssignment) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) GridDhtPartitionTopology(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionTopology) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) CacheEntryInfoCollection(org.apache.ignite.internal.processors.cache.CacheEntryInfoCollection) GridDhtLocalPartition(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLocalPartition) IgniteSpiException(org.apache.ignite.spi.IgniteSpiException) Map(java.util.Map) HashMap(java.util.HashMap) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)

Example 8 with ClusterTopologyCheckedException

use of org.apache.ignite.internal.cluster.ClusterTopologyCheckedException in project ignite by apache.

the class GridEventConsumeHandler method register.

/**
 * {@inheritDoc}
 */
@Override
public RegisterStatus register(final UUID nodeId, final UUID routineId, final GridKernalContext ctx) throws IgniteCheckedException {
    assert nodeId != null;
    assert routineId != null;
    assert ctx != null;
    if (cb != null)
        ctx.resource().injectGeneric(cb);
    final boolean loc = nodeId.equals(ctx.localNodeId());
    lsnr = new GridLocalEventListener() {

        /**
         * node ID, routine ID, event
         */
        private final Queue<T3<UUID, UUID, Event>> notificationQueue = new LinkedList<>();

        private boolean notificationInProgress;

        @Override
        public void onEvent(Event evt) {
            if (filter != null && !filter.apply(evt))
                return;
            if (loc) {
                if (!cb.apply(nodeId, evt))
                    ctx.continuous().stopRoutine(routineId);
            } else {
                if (ctx.discovery().node(nodeId) == null)
                    return;
                synchronized (notificationQueue) {
                    notificationQueue.add(new T3<>(nodeId, routineId, evt));
                    if (!notificationInProgress) {
                        ctx.pools().getSystemExecutorService().execute(new Runnable() {

                            @Override
                            public void run() {
                                if (!ctx.continuous().lockStopping())
                                    return;
                                try {
                                    while (true) {
                                        T3<UUID, UUID, Event> t3;
                                        synchronized (notificationQueue) {
                                            t3 = notificationQueue.poll();
                                            if (t3 == null) {
                                                notificationInProgress = false;
                                                return;
                                            }
                                        }
                                        try {
                                            Event evt = t3.get3();
                                            EventWrapper wrapper = new EventWrapper(evt);
                                            if (evt instanceof CacheEvent) {
                                                String cacheName = ((CacheEvent) evt).cacheName();
                                                ClusterNode node = ctx.discovery().node(t3.get1());
                                                if (node == null)
                                                    continue;
                                                if (ctx.config().isPeerClassLoadingEnabled() && ctx.discovery().cacheNode(node, cacheName)) {
                                                    GridCacheAdapter cache = ctx.cache().internalCache(cacheName);
                                                    if (cache != null && cache.context().deploymentEnabled()) {
                                                        wrapper.p2pMarshal(ctx.config().getMarshaller());
                                                        wrapper.cacheName = cacheName;
                                                        cache.context().deploy().prepare(wrapper);
                                                    }
                                                }
                                            }
                                            ctx.continuous().addNotification(t3.get1(), t3.get2(), wrapper, null, false, false);
                                        } catch (ClusterTopologyCheckedException ignored) {
                                        // No-op.
                                        } catch (Throwable e) {
                                            U.error(ctx.log(GridEventConsumeHandler.class), "Failed to send event notification to node: " + nodeId, e);
                                        }
                                    }
                                } finally {
                                    ctx.continuous().unlockStopping();
                                }
                            }
                        });
                        notificationInProgress = true;
                    }
                }
            }
        }
    };
    if (F.isEmpty(types))
        types = EVTS_ALL;
    p2pUnmarshalFut.listen((fut) -> {
        if (fut.error() == null) {
            try {
                initFilter(filter, ctx);
            } catch (IgniteCheckedException e) {
                throw F.wrap(e);
            }
            ctx.event().addLocalEventListener(lsnr, types);
        }
    });
    return RegisterStatus.REGISTERED;
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) GridLocalEventListener(org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener) LinkedList(java.util.LinkedList) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridCacheAdapter(org.apache.ignite.internal.processors.cache.GridCacheAdapter) CacheEvent(org.apache.ignite.events.CacheEvent) CacheEvent(org.apache.ignite.events.CacheEvent) Event(org.apache.ignite.events.Event) UUID(java.util.UUID) T3(org.apache.ignite.internal.util.typedef.T3) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)

Example 9 with ClusterTopologyCheckedException

use of org.apache.ignite.internal.cluster.ClusterTopologyCheckedException in project ignite by apache.

the class GridIoManager method sendToCustomTopic.

/**
 * @param nodeId Id of destination node.
 * @param topic Topic to send the message to.
 * @param msg Message to send.
 * @param plc Type of processing.
 * @throws IgniteCheckedException Thrown in case of any errors.
 */
public void sendToCustomTopic(UUID nodeId, Object topic, Message msg, byte plc) throws IgniteCheckedException {
    ClusterNode node = ctx.discovery().node(nodeId);
    if (node == null)
        throw new ClusterTopologyCheckedException("Failed to send message to node (has node left grid?): " + nodeId);
    sendToCustomTopic(node, topic, msg, plc);
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)

Example 10 with ClusterTopologyCheckedException

use of org.apache.ignite.internal.cluster.ClusterTopologyCheckedException in project ignite by apache.

the class GridIoManager method sendToGridTopic.

/**
 * @param nodeId Id of destination node.
 * @param topic Topic to send the message to.
 * @param msg Message to send.
 * @param plc Type of processing.
 * @throws IgniteCheckedException Thrown in case of any errors.
 */
public void sendToGridTopic(UUID nodeId, GridTopic topic, Message msg, byte plc) throws IgniteCheckedException {
    ClusterNode node = ctx.discovery().node(nodeId);
    if (node == null)
        throw new ClusterTopologyCheckedException("Failed to send message to node (has node left grid?): " + nodeId);
    send(node, topic, topic.ordinal(), msg, plc, false, 0, false, null, false);
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)

Aggregations

ClusterTopologyCheckedException (org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)112 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)82 ClusterNode (org.apache.ignite.cluster.ClusterNode)62 UUID (java.util.UUID)31 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)25 Map (java.util.Map)23 IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)22 HashMap (java.util.HashMap)20 ArrayList (java.util.ArrayList)18 IgniteException (org.apache.ignite.IgniteException)18 Collection (java.util.Collection)16 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)15 KeyCacheObject (org.apache.ignite.internal.processors.cache.KeyCacheObject)15 GridCacheEntryRemovedException (org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException)14 GridCacheContext (org.apache.ignite.internal.processors.cache.GridCacheContext)12 IgniteSpiException (org.apache.ignite.spi.IgniteSpiException)12 Nullable (org.jetbrains.annotations.Nullable)12 List (java.util.List)11 ConcurrentMap (java.util.concurrent.ConcurrentMap)11 ClusterTopologyServerNotFoundException (org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException)11