Search in sources :

Example 1 with IteratorWrapper

use of org.apache.ignite.internal.util.lang.GridIterableAdapter.IteratorWrapper 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 nodeId Node id.
 * @param supplyMsg Supply message.
 */
public void handleSupplyMessage(final UUID nodeId, final GridDhtPartitionSupplyMessage supplyMsg) {
    AffinityTopologyVersion topVer = supplyMsg.topologyVersion();
    RebalanceFuture fut = rebalanceFut;
    ClusterNode node = ctx.node(nodeId);
    fut.cancelLock.readLock().lock();
    try {
        String errMsg = null;
        if (fut.isDone())
            errMsg = "rebalance completed";
        else if (node == null)
            errMsg = "supplier has left cluster";
        else if (!rebalanceFut.isActual(supplyMsg.rebalanceId()))
            errMsg = "topology changed";
        if (errMsg != null) {
            if (log.isDebugEnabled()) {
                log.debug("Supply message has been ignored (" + errMsg + ") [" + demandRoutineInfo(nodeId, supplyMsg) + ']');
            }
            return;
        }
        if (log.isDebugEnabled())
            log.debug("Received supply message [" + demandRoutineInfo(nodeId, supplyMsg) + ']');
        // Check whether there were error during supplying process.
        Throwable msgExc = null;
        final GridDhtPartitionTopology top = grp.topology();
        if (supplyMsg.classError() != null)
            msgExc = supplyMsg.classError();
        else if (supplyMsg.error() != null)
            msgExc = supplyMsg.error();
        if (msgExc != null) {
            GridDhtPartitionMap partMap = top.localPartitionMap();
            Set<Integer> unstableParts = supplyMsg.infos().keySet().stream().filter(p -> partMap.get(p) == MOVING).collect(Collectors.toSet());
            U.error(log, "Rebalancing routine has failed, some partitions could be unavailable for reading" + " [" + demandRoutineInfo(nodeId, supplyMsg) + ", unavailablePartitions=" + S.compact(unstableParts) + ']', msgExc);
            fut.error(nodeId);
            return;
        }
        fut.receivedBytes.addAndGet(supplyMsg.messageSize());
        if (grp.sharedGroup()) {
            for (GridCacheContext cctx : grp.caches()) {
                if (cctx.statisticsEnabled()) {
                    long keysCnt = supplyMsg.keysForCache(cctx.cacheId());
                    if (keysCnt != -1)
                        cctx.cache().metrics0().onRebalancingKeysCountEstimateReceived(keysCnt);
                    // Can not be calculated per cache.
                    cctx.cache().metrics0().onRebalanceBatchReceived(supplyMsg.messageSize());
                }
            }
        } else {
            GridCacheContext cctx = grp.singleCacheContext();
            if (cctx.statisticsEnabled()) {
                if (supplyMsg.estimatedKeysCount() != -1)
                    cctx.cache().metrics0().onRebalancingKeysCountEstimateReceived(supplyMsg.estimatedKeysCount());
                cctx.cache().metrics0().onRebalanceBatchReceived(supplyMsg.messageSize());
            }
        }
        try {
            AffinityAssignment aff = grp.affinity().cachedAffinity(topVer);
            // Preload.
            for (Map.Entry<Integer, CacheEntryInfoCollection> e : supplyMsg.infos().entrySet()) {
                int p = e.getKey();
                if (aff.get(p).contains(ctx.localNode())) {
                    GridDhtLocalPartition part;
                    try {
                        part = top.localPartition(p, topVer, true);
                    } catch (GridDhtInvalidPartitionException err) {
                        assert !topVer.equals(top.lastTopologyChangeVersion());
                        if (log.isDebugEnabled()) {
                            log.debug("Failed to get partition for rebalancing [" + "grp=" + grp.cacheOrGroupName() + ", err=" + err + ", p=" + p + ", topVer=" + topVer + ", lastTopVer=" + top.lastTopologyChangeVersion() + ']');
                        }
                        continue;
                    }
                    assert part != null;
                    boolean last = supplyMsg.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.beforeApplyBatch(last);
                        try {
                            long[] byteRcv = { 0 };
                            GridIterableAdapter<GridCacheEntryInfo> infosWrap = new GridIterableAdapter<>(new IteratorWrapper<GridCacheEntryInfo>(e.getValue().infos().iterator()) {

                                /**
                                 * {@inheritDoc}
                                 */
                                @Override
                                public GridCacheEntryInfo nextX() throws IgniteCheckedException {
                                    GridCacheEntryInfo i = super.nextX();
                                    byteRcv[0] += i.marshalledSize(ctx.cacheObjectContext(i.cacheId()));
                                    return i;
                                }
                            });
                            try {
                                if (grp.mvccEnabled())
                                    mvccPreloadEntries(topVer, node, p, infosWrap);
                                else {
                                    preloadEntries(topVer, part, infosWrap);
                                    rebalanceFut.onReceivedKeys(p, e.getValue().infos().size(), node);
                                }
                            } catch (GridDhtInvalidPartitionException ignored) {
                                if (log.isDebugEnabled())
                                    log.debug("Partition became invalid during rebalancing (will ignore): " + p);
                            }
                            fut.processed.get(p).increment();
                            fut.onReceivedBytes(p, byteRcv[0], node);
                            // If message was last for this partition, then we take ownership.
                            if (last)
                                ownPartition(fut, p, nodeId, supplyMsg);
                        } finally {
                            part.release();
                        }
                    } else {
                        if (last)
                            fut.partitionDone(nodeId, p, false);
                        if (log.isDebugEnabled())
                            log.debug("Skipping rebalancing partition (state is not MOVING): " + '[' + demandRoutineInfo(nodeId, supplyMsg) + ", p=" + p + ']');
                    }
                } else {
                    fut.partitionDone(nodeId, p, false);
                    if (log.isDebugEnabled())
                        log.debug("Skipping rebalancing partition (affinity changed): " + '[' + demandRoutineInfo(nodeId, supplyMsg) + ", p=" + p + ']');
                }
            }
            // Only request partitions based on latest topology version.
            for (Integer miss : supplyMsg.missed()) {
                if (aff.get(miss).contains(ctx.localNode()))
                    fut.partitionMissed(nodeId, miss);
            }
            for (Integer miss : supplyMsg.missed()) fut.partitionDone(nodeId, miss, false);
            GridDhtPartitionDemandMessage d = new GridDhtPartitionDemandMessage(supplyMsg.rebalanceId(), supplyMsg.topologyVersion(), grp.groupId());
            d.timeout(grp.preloader().timeout());
            if (!fut.isDone()) {
                // Send demand message.
                try {
                    ctx.io().sendOrderedMessage(node, d.topic(), d.convertIfNeeded(node.version()), grp.ioPolicy(), grp.preloader().timeout());
                    if (log.isDebugEnabled())
                        log.debug("Send next demand message [" + demandRoutineInfo(nodeId, supplyMsg) + "]");
                } catch (ClusterTopologyCheckedException e) {
                    if (log.isDebugEnabled())
                        log.debug("Supplier has left [" + demandRoutineInfo(nodeId, supplyMsg) + ", errMsg=" + e.getMessage() + ']');
                }
            } else {
                if (log.isDebugEnabled())
                    log.debug("Will not request next demand message [" + demandRoutineInfo(nodeId, supplyMsg) + ", rebalanceFuture=" + fut + ']');
            }
        } catch (IgniteSpiException | IgniteCheckedException e) {
            fut.error(nodeId);
            LT.error(log, e, "Error during rebalancing [" + demandRoutineInfo(nodeId, supplyMsg) + ", err=" + e + ']');
        }
    } finally {
        fut.cancelLock.readLock().unlock();
    }
}
Also used : IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) GridFutureAdapter(org.apache.ignite.internal.util.future.GridFutureAdapter) GridFinishedFuture(org.apache.ignite.internal.util.future.GridFinishedFuture) Collectors.counting(java.util.stream.Collectors.counting) IteratorWrapper(org.apache.ignite.internal.util.lang.GridIterableAdapter.IteratorWrapper) CacheRebalanceMode(org.apache.ignite.cache.CacheRebalanceMode) EVT_CACHE_REBALANCE_STARTED(org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_STARTED) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) EVT_CACHE_REBALANCE_STOPPED(org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_STOPPED) EVT_CACHE_REBALANCE_PART_LOADED(org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_PART_LOADED) MetricUtils.metricName(org.apache.ignite.internal.processors.metric.impl.MetricUtils.metricName) Collectors.toSet(java.util.stream.Collectors.toSet) CACHE_GROUP_METRICS_PREFIX(org.apache.ignite.internal.processors.cache.CacheGroupMetricsImpl.CACHE_GROUP_METRICS_PREFIX) GridCacheEntryInfo(org.apache.ignite.internal.processors.cache.GridCacheEntryInfo) IgniteInClosure(org.apache.ignite.lang.IgniteInClosure) AtomicReferenceFieldUpdater(java.util.concurrent.atomic.AtomicReferenceFieldUpdater) GridToStringExclude(org.apache.ignite.internal.util.tostring.GridToStringExclude) Collection(java.util.Collection) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) DR_PRELOAD(org.apache.ignite.internal.processors.dr.GridDrType.DR_PRELOAD) Set(java.util.Set) NavigableSet(java.util.NavigableSet) UUID(java.util.UUID) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) CacheDataRow(org.apache.ignite.internal.processors.cache.persistence.CacheDataRow) Collectors(java.util.stream.Collectors) Nullable(org.jetbrains.annotations.Nullable) List(java.util.List) IgniteConfiguration(org.apache.ignite.configuration.IgniteConfiguration) Stream(java.util.stream.Stream) GridDhtPartitionTopology(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionTopology) CU(org.apache.ignite.internal.util.typedef.internal.CU) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) IntHashMap(org.apache.ignite.internal.util.collection.IntHashMap) Objects.nonNull(java.util.Objects.nonNull) GridCacheEntryEx(org.apache.ignite.internal.processors.cache.GridCacheEntryEx) EVT_CACHE_REBALANCE_OBJECT_LOADED(org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_OBJECT_LOADED) GridCachePartitionExchangeManager(org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager) LongAdder(java.util.concurrent.atomic.LongAdder) DR_NONE(org.apache.ignite.internal.processors.dr.GridDrType.DR_NONE) DiscoveryEvent(org.apache.ignite.events.DiscoveryEvent) Collectors.partitioningBy(java.util.stream.Collectors.partitioningBy) IgniteSpiException(org.apache.ignite.spi.IgniteSpiException) CacheEntryInfoCollection(org.apache.ignite.internal.processors.cache.CacheEntryInfoCollection) CheckpointProgress(org.apache.ignite.internal.processors.cache.persistence.checkpoint.CheckpointProgress) GridCompoundFuture(org.apache.ignite.internal.util.future.GridCompoundFuture) IgnitePredicateX(org.apache.ignite.internal.util.lang.IgnitePredicateX) U(org.apache.ignite.internal.util.typedef.internal.U) HashMap(java.util.HashMap) IgniteLogger(org.apache.ignite.IgniteLogger) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) AtomicReference(java.util.concurrent.atomic.AtomicReference) CacheGroupContext(org.apache.ignite.internal.processors.cache.CacheGroupContext) LT(org.apache.ignite.internal.util.typedef.internal.LT) ArrayList(java.util.ArrayList) AffinityAssignment(org.apache.ignite.internal.processors.affinity.AffinityAssignment) HashSet(java.util.HashSet) ClusterNode(org.apache.ignite.cluster.ClusterNode) CI1(org.apache.ignite.internal.util.typedef.CI1) GridTimeoutObjectAdapter(org.apache.ignite.internal.processors.timeout.GridTimeoutObjectAdapter) S(org.apache.ignite.internal.util.typedef.internal.S) MOVING(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState.MOVING) IgniteInterruptedCheckedException(org.apache.ignite.internal.IgniteInterruptedCheckedException) PAGE_SNAPSHOT_TAKEN(org.apache.ignite.internal.processors.cache.persistence.CheckpointState.PAGE_SNAPSHOT_TAKEN) FINISHED(org.apache.ignite.internal.processors.cache.persistence.CheckpointState.FINISHED) F(org.apache.ignite.internal.util.typedef.F) GridIterableAdapter(org.apache.ignite.internal.util.lang.GridIterableAdapter) Iterator(java.util.Iterator) GridTimeoutObject(org.apache.ignite.internal.processors.timeout.GridTimeoutObject) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException) TTL_ETERNAL(org.apache.ignite.internal.processors.cache.GridCacheUtils.TTL_ETERNAL) GridMutableLong(org.apache.ignite.internal.util.GridMutableLong) GridDhtInvalidPartitionException(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtInvalidPartitionException) MetricRegistry(org.apache.ignite.internal.processors.metric.MetricRegistry) GridToStringInclude(org.apache.ignite.internal.util.tostring.GridToStringInclude) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) GridDhtLocalPartition(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition) GridCacheSharedContext(org.apache.ignite.internal.processors.cache.GridCacheSharedContext) CacheConfiguration(org.apache.ignite.configuration.CacheConfiguration) WalStateManager(org.apache.ignite.internal.processors.cache.WalStateManager) GridPlainRunnable(org.apache.ignite.internal.util.lang.GridPlainRunnable) CacheMetricsImpl(org.apache.ignite.internal.processors.cache.CacheMetricsImpl) GridCacheMvccEntryInfo(org.apache.ignite.internal.processors.cache.GridCacheMvccEntryInfo) Collections(java.util.Collections) TxState(org.apache.ignite.internal.processors.cache.mvcc.txlog.TxState) PRELOAD_SIZE_UNDER_CHECKPOINT_LOCK(org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl.PRELOAD_SIZE_UNDER_CHECKPOINT_LOCK) AffinityAssignment(org.apache.ignite.internal.processors.affinity.AffinityAssignment) GridDhtPartitionTopology(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionTopology) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) CacheEntryInfoCollection(org.apache.ignite.internal.processors.cache.CacheEntryInfoCollection) GridDhtLocalPartition(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition) IgniteSpiException(org.apache.ignite.spi.IgniteSpiException) ClusterNode(org.apache.ignite.cluster.ClusterNode) GridCacheEntryInfo(org.apache.ignite.internal.processors.cache.GridCacheEntryInfo) GridDhtInvalidPartitionException(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtInvalidPartitionException) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) GridIterableAdapter(org.apache.ignite.internal.util.lang.GridIterableAdapter) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) IntHashMap(org.apache.ignite.internal.util.collection.IntHashMap) HashMap(java.util.HashMap) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)

Aggregations

ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 Collections (java.util.Collections)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Iterator (java.util.Iterator)1 List (java.util.List)1 Map (java.util.Map)1 NavigableSet (java.util.NavigableSet)1 Objects.nonNull (java.util.Objects.nonNull)1 Set (java.util.Set)1 UUID (java.util.UUID)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 TimeUnit (java.util.concurrent.TimeUnit)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 AtomicLong (java.util.concurrent.atomic.AtomicLong)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 AtomicReferenceFieldUpdater (java.util.concurrent.atomic.AtomicReferenceFieldUpdater)1 LongAdder (java.util.concurrent.atomic.LongAdder)1 ReentrantReadWriteLock (java.util.concurrent.locks.ReentrantReadWriteLock)1