use of org.apache.ignite.internal.processors.cache.ExchangeDiscoveryEvents in project ignite by apache.
the class GridDhtPartitionTopologyImpl method beforeExchange.
/**
* {@inheritDoc}
*/
@Override
public void beforeExchange(GridDhtPartitionsExchangeFuture exchFut, boolean affReady, boolean updateMoving) throws IgniteCheckedException {
ClusterNode loc = ctx.localNode();
ctx.database().checkpointReadLock();
try {
synchronized (ctx.exchange().interruptLock()) {
if (Thread.currentThread().isInterrupted())
throw new IgniteInterruptedCheckedException("Thread is interrupted: " + Thread.currentThread());
U.writeLock(lock);
try {
if (stopping)
return;
assert lastTopChangeVer.equals(exchFut.initialVersion()) : "Invalid topology version [topVer=" + lastTopChangeVer + ", exchId=" + exchFut.exchangeId() + ']';
ExchangeDiscoveryEvents evts = exchFut.context().events();
if (affReady) {
assert grp.affinity().lastVersion().equals(evts.topologyVersion()) : "Invalid affinity version [" + "grp=" + grp.cacheOrGroupName() + ", affVer=" + grp.affinity().lastVersion() + ", evtsVer=" + evts.topologyVersion() + ']';
lastTopChangeVer = readyTopVer = evts.topologyVersion();
}
ClusterNode oldest = discoCache.oldestAliveServerNode();
if (log.isDebugEnabled()) {
log.debug("Partition map beforeExchange [grp=" + grp.cacheOrGroupName() + ", exchId=" + exchFut.exchangeId() + ", fullMap=" + fullMapString() + ']');
}
long updateSeq = this.updateSeq.incrementAndGet();
cntrMap.clear();
boolean grpStarted = exchFut.cacheGroupAddedOnExchange(grp.groupId(), grp.receivedFrom());
// If this is the oldest node.
if (oldest != null && (loc.equals(oldest) || grpStarted)) {
if (node2part == null) {
node2part = new GridDhtPartitionFullMap(oldest.id(), oldest.order(), updateSeq);
if (log.isDebugEnabled()) {
log.debug("Created brand new full topology map on oldest node [" + "grp=" + grp.cacheOrGroupName() + ", exchId=" + exchFut.exchangeId() + ", fullMap=" + fullMapString() + ']');
}
} else if (!node2part.valid()) {
node2part = new GridDhtPartitionFullMap(oldest.id(), oldest.order(), updateSeq, node2part, false);
if (log.isDebugEnabled()) {
log.debug("Created new full topology map on oldest node [" + "grp=" + grp.cacheOrGroupName() + ", exchId=" + exchFut.exchangeId() + ", fullMap=" + node2part + ']');
}
} else if (!node2part.nodeId().equals(loc.id())) {
node2part = new GridDhtPartitionFullMap(oldest.id(), oldest.order(), updateSeq, node2part, false);
if (log.isDebugEnabled()) {
log.debug("Copied old map into new map on oldest node (previous oldest node left) [" + "grp=" + grp.cacheOrGroupName() + ", exchId=" + exchFut.exchangeId() + ", fullMap=" + fullMapString() + ']');
}
}
}
if (evts.hasServerLeft()) {
List<DiscoveryEvent> evts0 = evts.events();
for (int i = 0; i < evts0.size(); i++) {
DiscoveryEvent evt = evts0.get(i);
if (ExchangeDiscoveryEvents.serverLeftEvent(evt))
removeNode(evt.eventNode().id());
}
}
if (grp.affinityNode()) {
if (grpStarted || exchFut.firstEvent().type() == EVT_DISCOVERY_CUSTOM_EVT || exchFut.serverNodeDiscoveryEvent()) {
if (affReady) {
assert grp.affinity().lastVersion().equals(evts.topologyVersion());
initPartitions0(evts.topologyVersion(), exchFut, updateSeq);
} else {
assert !exchFut.context().mergeExchanges();
List<List<ClusterNode>> aff = grp.affinity().idealAssignment();
createPartitions(exchFut.initialVersion(), aff, updateSeq);
}
}
}
consistencyCheck();
if (updateMoving) {
assert grp.affinity().lastVersion().equals(evts.topologyVersion());
createMovingPartitions(grp.affinity().readyAffinity(evts.topologyVersion()));
}
if (log.isDebugEnabled()) {
log.debug("Partition map after beforeExchange [grp=" + grp.cacheOrGroupName() + ", " + "exchId=" + exchFut.exchangeId() + ", fullMap=" + fullMapString() + ']');
}
} finally {
lock.writeLock().unlock();
}
}
} finally {
ctx.database().checkpointReadUnlock();
}
}
use of org.apache.ignite.internal.processors.cache.ExchangeDiscoveryEvents in project ignite by apache.
the class GridDhtPartitionsExchangeFuture method onDone.
/**
* {@inheritDoc}
*/
@Override
public boolean onDone(@Nullable AffinityTopologyVersion res, @Nullable Throwable err) {
assert res != null || err != null : "TopVer=" + res + ", err=" + err;
if (isDone() || !done.compareAndSet(false, true))
return false;
if (log.isInfoEnabled()) {
log.info("Finish exchange future [startVer=" + initialVersion() + ", resVer=" + res + ", err=" + err + ", rebalanced=" + rebalanced() + ", wasRebalanced=" + wasRebalanced() + ']');
}
if (res != null) {
span.addTag(SpanTags.tag(SpanTags.RESULT, SpanTags.TOPOLOGY_VERSION, SpanTags.MAJOR), () -> String.valueOf(res.topologyVersion()));
span.addTag(SpanTags.tag(SpanTags.RESULT, SpanTags.TOPOLOGY_VERSION, SpanTags.MINOR), () -> String.valueOf(res.minorTopologyVersion()));
}
if (err != null) {
Throwable errf = err;
span.addTag(SpanTags.ERROR, errf::toString);
}
boolean cleanIdxRebuildFutures = true;
try {
waitUntilNewCachesAreRegistered();
if (err == null && !cctx.kernalContext().clientNode() && (serverNodeDiscoveryEvent() || affChangeMsg != null)) {
for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
if (!cacheCtx.affinityNode() || cacheCtx.isLocal())
continue;
cacheCtx.continuousQueries().flushOnExchangeDone(res);
}
}
if (err == null) {
if (centralizedAff || forceAffReassignment) {
assert !exchCtx.mergeExchanges();
Collection<CacheGroupContext> grpToRefresh = U.newHashSet(cctx.cache().cacheGroups().size());
for (CacheGroupContext grp : cctx.cache().cacheGroups()) {
if (grp.isLocal())
continue;
try {
if (grp.topology().initPartitionsWhenAffinityReady(res, this))
grpToRefresh.add(grp);
} catch (IgniteInterruptedCheckedException e) {
U.error(log, "Failed to initialize partitions.", e);
}
}
if (!grpToRefresh.isEmpty()) {
if (log.isDebugEnabled())
log.debug("Refresh partitions due to partitions initialized when affinity ready [" + grpToRefresh.stream().map(CacheGroupContext::name).collect(Collectors.toList()) + ']');
cctx.exchange().refreshPartitions(grpToRefresh);
}
}
for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
GridCacheContext drCacheCtx = cacheCtx.isNear() ? cacheCtx.near().dht().context() : cacheCtx;
if (drCacheCtx.isDrEnabled()) {
try {
drCacheCtx.dr().onExchange(res, exchId.isLeft(), activateCluster());
} catch (IgniteCheckedException e) {
U.error(log, "Failed to notify DR: " + e, e);
}
}
}
if (exchCtx.events().hasServerLeft() || activateCluster())
detectLostPartitions(res);
Map<Integer, CacheGroupValidation> m = U.newHashMap(cctx.cache().cacheGroups().size());
for (CacheGroupContext grp : cctx.cache().cacheGroups()) {
CacheGroupValidation valRes = validateCacheGroup(grp, events().lastEvent().topologyNodes());
if (!valRes.isValid() || valRes.hasLostPartitions())
m.put(grp.groupId(), valRes);
}
grpValidRes = m;
}
if (!cctx.localNode().isClient())
tryToPerformLocalSnapshotOperation();
if (err == null)
cctx.coordinators().onExchangeDone(events().discoveryCache());
for (PartitionsExchangeAware comp : cctx.exchange().exchangeAwareComponents()) comp.onDoneBeforeTopologyUnlock(this);
// Create and destroy caches and cache proxies.
cctx.cache().onExchangeDone(initialVersion(), exchActions, err);
Map<T2<Integer, Integer>, Long> localReserved = partHistSuppliers.getReservations(cctx.localNodeId());
if (localReserved != null) {
boolean success = cctx.database().reserveHistoryForPreloading(localReserved);
if (!success) {
log.warning("Could not reserve history for historical rebalance " + "(possible it happened because WAL space is exhausted).");
}
}
cctx.database().releaseHistoryForExchange();
if (err == null) {
cctx.database().rebuildIndexesIfNeeded(this);
cleanIdxRebuildFutures = false;
for (CacheGroupContext grp : cctx.cache().cacheGroups()) {
if (!grp.isLocal())
grp.topology().onExchangeDone(this, grp.affinity().readyAffinity(res), false);
}
if (changedAffinity())
cctx.walState().disableGroupDurabilityForPreloading(this);
}
} catch (Throwable t) {
// In any case, this exchange future has to be completed. The original error should be preserved if exists.
if (err != null)
t.addSuppressed(err);
err = t;
}
final Throwable err0 = err;
if (err0 != null && cleanIdxRebuildFutures)
cctx.kernalContext().query().removeIndexRebuildFuturesOnExchange(this, null);
// Should execute this listener first, before any external listeners.
// Listeners use stack as data structure.
listen(f -> {
// Update last finished future in the first.
cctx.exchange().lastFinishedFuture(this);
// Complete any affReady futures and update last exchange done version.
cctx.exchange().onExchangeDone(res, initialVersion(), err0);
cctx.cache().completeProxyRestart(resolveCacheRequests(exchActions), initialVersion(), res);
if (exchActions != null && err0 == null)
exchActions.completeRequestFutures(cctx, null);
if (stateChangeExchange() && err0 == null)
cctx.kernalContext().state().onStateChangeExchangeDone(exchActions.stateChangeRequest());
});
if (super.onDone(res, err)) {
afterLsnrCompleteFut.onDone();
span.addLog(() -> "Completed partition exchange");
span.end();
if (err == null) {
updateDurationHistogram(System.currentTimeMillis() - initTime);
cctx.exchange().clusterRebalancedMetric().value(rebalanced());
}
if (log.isInfoEnabled()) {
log.info("Completed partition exchange [localNode=" + cctx.localNodeId() + ", exchange=" + (log.isDebugEnabled() ? this : shortInfo()) + ", topVer=" + topologyVersion() + "]");
if (err == null) {
timeBag.finishGlobalStage("Exchange done");
// Collect all stages timings.
List<String> timings = timeBag.stagesTimings();
if (discoveryLag != null && discoveryLag.get1() != 0)
timings.add("Discovery lag=" + discoveryLag.get1() + " ms, Latest started node id=" + discoveryLag.get2());
log.info(exchangeTimingsLogMessage("Exchange timings", timings));
List<String> localTimings = timeBag.longestLocalStagesTimings(3);
log.info(exchangeTimingsLogMessage("Exchange longest local stages", localTimings));
}
}
initFut.onDone(err == null);
cctx.exchange().latch().dropClientLatches(initialVersion());
if (exchCtx != null && exchCtx.events().hasServerLeft()) {
ExchangeDiscoveryEvents evts = exchCtx.events();
for (DiscoveryEvent evt : evts.events()) {
if (serverLeftEvent(evt)) {
for (CacheGroupContext grp : cctx.cache().cacheGroups()) grp.affinityFunction().removeNode(evt.eventNode().id());
}
}
}
for (PartitionsExchangeAware comp : cctx.exchange().exchangeAwareComponents()) comp.onDoneAfterTopologyUnlock(this);
if (firstDiscoEvt instanceof DiscoveryCustomEvent)
((DiscoveryCustomEvent) firstDiscoEvt).customMessage(null);
if (err == null) {
if (exchCtx != null && (exchCtx.events().hasServerLeft() || exchCtx.events().hasServerJoin())) {
ExchangeDiscoveryEvents evts = exchCtx.events();
for (DiscoveryEvent evt : evts.events()) {
if (serverLeftEvent(evt) || serverJoinEvent(evt))
logExchange(evt);
}
}
}
return true;
}
return false;
}
use of org.apache.ignite.internal.processors.cache.ExchangeDiscoveryEvents in project ignite by apache.
the class GridDhtPartitionTopologyImpl method beforeExchange.
/**
* {@inheritDoc}
*/
@Override
public void beforeExchange(GridDhtPartitionsExchangeFuture exchFut, boolean affReady, boolean updateMoving) throws IgniteCheckedException {
ctx.database().checkpointReadLock();
try {
U.writeLock(lock);
try {
if (stopping)
return;
assert lastTopChangeVer.equals(exchFut.initialVersion()) : "Invalid topology version [topVer=" + lastTopChangeVer + ", exchId=" + exchFut.exchangeId() + ']';
ExchangeDiscoveryEvents evts = exchFut.context().events();
if (affReady) {
assert grp.affinity().lastVersion().equals(evts.topologyVersion()) : "Invalid affinity version [" + "grp=" + grp.cacheOrGroupName() + ", affVer=" + grp.affinity().lastVersion() + ", evtsVer=" + evts.topologyVersion() + ']';
lastTopChangeVer = readyTopVer = evts.topologyVersion();
discoCache = evts.discoveryCache();
}
if (log.isDebugEnabled()) {
log.debug("Partition map beforeExchange [grp=" + grp.cacheOrGroupName() + ", exchId=" + exchFut.exchangeId() + ", fullMap=" + fullMapString() + ']');
}
long updateSeq = this.updateSeq.incrementAndGet();
if (exchFut.exchangeType() == ALL && !exchFut.rebalanced())
cntrMap.clear();
initializeFullMap(updateSeq);
boolean grpStarted = exchFut.cacheGroupAddedOnExchange(grp.groupId(), grp.receivedFrom());
if (evts.hasServerLeft()) {
for (DiscoveryEvent evt : evts.events()) {
if (ExchangeDiscoveryEvents.serverLeftEvent(evt))
removeNode(evt.eventNode().id());
}
} else if (affReady && grpStarted && exchFut.exchangeType() == NONE) {
assert !exchFut.context().mergeExchanges() : exchFut;
assert node2part != null && node2part.valid() : exchFut;
// Initialize node maps if group was started from joining client.
final List<ClusterNode> nodes = exchFut.firstEventCache().cacheGroupAffinityNodes(grp.groupId());
for (ClusterNode node : nodes) {
if (!node2part.containsKey(node.id()) && ctx.discovery().alive(node)) {
final GridDhtPartitionMap partMap = new GridDhtPartitionMap(node.id(), 1L, exchFut.initialVersion(), new GridPartitionStateMap(), false);
final AffinityAssignment aff = grp.affinity().cachedAffinity(exchFut.initialVersion());
for (Integer p0 : aff.primaryPartitions(node.id())) partMap.put(p0, OWNING);
for (Integer p0 : aff.backupPartitions(node.id())) partMap.put(p0, OWNING);
node2part.put(node.id(), partMap);
}
}
}
if (grp.affinityNode()) {
if (grpStarted || exchFut.firstEvent().type() == EVT_DISCOVERY_CUSTOM_EVT || exchFut.serverNodeDiscoveryEvent()) {
AffinityTopologyVersion affVer;
List<List<ClusterNode>> affAssignment;
if (affReady) {
affVer = evts.topologyVersion();
assert grp.affinity().lastVersion().equals(affVer) : "Invalid affinity [topVer=" + grp.affinity().lastVersion() + ", grp=" + grp.cacheOrGroupName() + ", affVer=" + affVer + ", fut=" + exchFut + ']';
affAssignment = grp.affinity().readyAssignments(affVer);
} else {
assert !exchFut.context().mergeExchanges();
affVer = exchFut.initialVersion();
affAssignment = grp.affinity().idealAssignmentRaw();
}
initPartitions(affVer, affAssignment, exchFut, updateSeq);
}
}
consistencyCheck();
if (updateMoving) {
assert grp.affinity().lastVersion().equals(evts.topologyVersion());
createMovingPartitions(grp.affinity().readyAffinity(evts.topologyVersion()));
}
if (log.isDebugEnabled()) {
log.debug("Partition map after beforeExchange [grp=" + grp.cacheOrGroupName() + ", " + "exchId=" + exchFut.exchangeId() + ", fullMap=" + fullMapString() + ']');
}
if (log.isTraceEnabled()) {
log.trace("Partition states after beforeExchange [grp=" + grp.cacheOrGroupName() + ", exchId=" + exchFut.exchangeId() + ", states=" + dumpPartitionStates() + ']');
}
} finally {
lock.writeLock().unlock();
}
} finally {
ctx.database().checkpointReadUnlock();
}
}
use of org.apache.ignite.internal.processors.cache.ExchangeDiscoveryEvents in project ignite by apache.
the class GridClientPartitionTopology method beforeExchange.
/**
* {@inheritDoc}
*/
@Override
public void beforeExchange(GridDhtPartitionsExchangeFuture exchFut, boolean initParts, boolean updateMoving) throws IgniteCheckedException {
ClusterNode loc = cctx.localNode();
U.writeLock(lock);
try {
if (stopping)
return;
discoCache = exchFut.events().discoveryCache();
beforeExchange0(loc, exchFut);
if (updateMoving) {
ExchangeDiscoveryEvents evts = exchFut.context().events();
GridAffinityAssignmentCache aff = cctx.affinity().affinity(grpId);
assert aff.lastVersion().equals(evts.topologyVersion());
createMovingPartitions(aff.readyAffinity(evts.topologyVersion()));
}
} finally {
lock.writeLock().unlock();
}
}
use of org.apache.ignite.internal.processors.cache.ExchangeDiscoveryEvents in project ignite by apache.
the class GridClientPartitionTopology method beforeExchange.
/**
* {@inheritDoc}
*/
@Override
public void beforeExchange(GridDhtPartitionsExchangeFuture exchFut, boolean initParts, boolean updateMoving) throws IgniteCheckedException {
ClusterNode loc = cctx.localNode();
U.writeLock(lock);
try {
if (stopping)
return;
discoCache = exchFut.events().discoveryCache();
beforeExchange0(loc, exchFut);
if (updateMoving) {
ExchangeDiscoveryEvents evts = exchFut.context().events();
GridAffinityAssignmentCache aff = cctx.affinity().affinity(grpId);
assert aff.lastVersion().equals(evts.topologyVersion());
createMovingPartitions(aff.readyAffinity(evts.topologyVersion()));
}
} finally {
lock.writeLock().unlock();
}
}
Aggregations