use of org.apache.ignite.internal.processors.affinity.GridAffinityAssignmentCache in project ignite by apache.
the class CacheAffinitySharedManager method onCacheChangeRequest.
/**
* Called on exchange initiated for cache start/stop request.
*
* @param fut Exchange future.
* @param crd Coordinator flag.
* @param exchActions Cache change requests.
* @throws IgniteCheckedException If failed.
* @return {@code True} if client-only exchange is needed.
*/
public boolean onCacheChangeRequest(final GridDhtPartitionsExchangeFuture fut, boolean crd, ExchangeActions exchActions) throws IgniteCheckedException {
assert exchActions != null && !exchActions.empty() : exchActions;
updateCachesInfo(exchActions);
// Affinity did not change for existing caches.
forAllCaches(crd && lateAffAssign, new IgniteInClosureX<GridAffinityAssignmentCache>() {
@Override
public void applyx(GridAffinityAssignmentCache aff) throws IgniteCheckedException {
if (fut.stopping(aff.cacheId()))
return;
aff.clientEventTopologyChange(fut.discoveryEvent(), fut.topologyVersion());
}
});
for (ExchangeActions.ActionData action : exchActions.newAndClientCachesStartRequests()) {
DynamicCacheDescriptor cacheDesc = action.descriptor();
DynamicCacheChangeRequest req = action.request();
boolean startCache;
NearCacheConfiguration nearCfg = null;
if (cctx.localNodeId().equals(req.initiatingNodeId())) {
startCache = true;
nearCfg = req.nearCacheConfiguration();
} else {
startCache = cctx.cacheContext(action.descriptor().cacheId()) == null && CU.affinityNode(cctx.localNode(), req.startCacheConfiguration().getNodeFilter());
}
try {
if (startCache) {
cctx.cache().prepareCacheStart(cacheDesc, nearCfg, fut.topologyVersion());
if (fut.cacheAddedOnExchange(cacheDesc.cacheId(), cacheDesc.receivedFrom())) {
if (fut.discoCache().cacheAffinityNodes(req.cacheName()).isEmpty())
U.quietAndWarn(log, "No server nodes found for cache client: " + req.cacheName());
}
}
if (!crd || !lateAffAssign) {
GridCacheContext cacheCtx = cctx.cacheContext(cacheDesc.cacheId());
if (cacheCtx != null && !cacheCtx.isLocal()) {
boolean clientCacheStarted = req.clientStartOnly() && req.initiatingNodeId().equals(cctx.localNodeId());
if (clientCacheStarted)
initAffinity(cacheDesc, cacheCtx.affinity().affinityCache(), fut, lateAffAssign);
else if (!req.clientStartOnly()) {
assert fut.topologyVersion().equals(cacheCtx.startTopologyVersion());
GridAffinityAssignmentCache aff = cacheCtx.affinity().affinityCache();
assert aff.lastVersion().equals(AffinityTopologyVersion.NONE) : aff.lastVersion();
List<List<ClusterNode>> assignment = aff.calculate(fut.topologyVersion(), fut.discoveryEvent(), fut.discoCache());
aff.initialize(fut.topologyVersion(), assignment);
}
}
} else
initStartedCacheOnCoordinator(fut, cacheDesc.cacheId());
} catch (IgniteCheckedException e) {
U.error(log, "Failed to initialize cache. Will try to rollback cache start routine. " + "[cacheName=" + req.cacheName() + ']', e);
cctx.cache().forceCloseCache(fut.topologyVersion(), action, e);
}
}
for (DynamicCacheChangeRequest req : exchActions.closeRequests(cctx.localNodeId())) {
Integer cacheId = CU.cacheId(req.cacheName());
cctx.cache().blockGateway(req);
if (crd) {
GridCacheContext cacheCtx = cctx.cacheContext(cacheId);
// Client cache was stopped, need create 'client' CacheHolder.
if (cacheCtx != null && !cacheCtx.affinityNode()) {
CacheHolder cache = caches.remove(cacheId);
assert !cache.client() : cache;
cache = CacheHolder2.create(cctx, cctx.cache().cacheDescriptor(cacheId), fut, cache.affinity());
caches.put(cacheId, cache);
}
}
}
Set<Integer> stoppedCaches = null;
for (ExchangeActions.ActionData action : exchActions.cacheStopRequests()) {
DynamicCacheDescriptor desc = action.descriptor();
cctx.cache().blockGateway(action.request());
if (crd && lateAffAssign && desc.cacheConfiguration().getCacheMode() != LOCAL) {
CacheHolder cache = caches.remove(desc.cacheId());
assert cache != null : action.request();
if (stoppedCaches == null)
stoppedCaches = new HashSet<>();
stoppedCaches.add(cache.cacheId());
cctx.io().removeHandler(desc.cacheId(), GridDhtAffinityAssignmentResponse.class);
}
}
if (stoppedCaches != null) {
boolean notify = false;
synchronized (mux) {
if (waitInfo != null) {
for (Integer cacheId : stoppedCaches) {
boolean rmv = waitInfo.waitCaches.remove(cacheId) != null;
if (rmv) {
notify = true;
waitInfo.assignments.remove(cacheId);
}
}
}
}
if (notify) {
final AffinityTopologyVersion topVer = affCalcVer;
cctx.kernalContext().closure().runLocalSafe(new Runnable() {
@Override
public void run() {
onCacheStopped(topVer);
}
});
}
}
return exchActions.clientOnlyExchange();
}
use of org.apache.ignite.internal.processors.affinity.GridAffinityAssignmentCache in project ignite by apache.
the class GridCachePartitionExchangeManager method createPartitionsFullMessage.
/**
* @param nodes Target nodes.
* @param exchId Non-null exchange ID if message is created for exchange.
* @param lastVer Last version.
* @param compress {@code True} if it is possible to use compression for message.
* @return Message.
*/
public GridDhtPartitionsFullMessage createPartitionsFullMessage(Collection<ClusterNode> nodes, @Nullable final GridDhtPartitionExchangeId exchId, @Nullable GridCacheVersion lastVer, final boolean compress) {
final GridDhtPartitionsFullMessage m = new GridDhtPartitionsFullMessage(exchId, lastVer, exchId != null ? exchId.topologyVersion() : AffinityTopologyVersion.NONE);
m.compress(compress);
final Map<Object, T2<Integer, GridDhtPartitionFullMap>> dupData = new HashMap<>();
cctx.forAllCaches(new IgniteInClosure<GridCacheContext>() {
@Override
public void apply(GridCacheContext cacheCtx) {
if (!cacheCtx.isLocal()) {
boolean ready;
if (exchId != null) {
AffinityTopologyVersion startTopVer = cacheCtx.startTopologyVersion();
ready = startTopVer.compareTo(exchId.topologyVersion()) <= 0;
} else
ready = cacheCtx.started();
if (ready) {
GridAffinityAssignmentCache affCache = cacheCtx.affinity().affinityCache();
GridDhtPartitionFullMap locMap = cacheCtx.topology().partitionMap(true);
addFullPartitionsMap(m, dupData, compress, cacheCtx.cacheId(), locMap, affCache.similarAffinityKey());
if (exchId != null)
m.addPartitionUpdateCounters(cacheCtx.cacheId(), cacheCtx.topology().updateCounters(true));
}
}
}
});
// It is important that client topologies be added after contexts.
for (GridClientPartitionTopology top : cctx.exchange().clientTopologies()) {
GridDhtPartitionFullMap map = top.partitionMap(true);
addFullPartitionsMap(m, dupData, compress, top.cacheId(), map, top.similarAffinityKey());
if (exchId != null)
m.addPartitionUpdateCounters(top.cacheId(), top.updateCounters(true));
}
return m;
}
use of org.apache.ignite.internal.processors.affinity.GridAffinityAssignmentCache in project ignite by apache.
the class AffinityHistoryCleanupTest method checkHistory.
/**
* @param ignite Node.
* @param expHist Expected history.
* @param expSize Expected 'non client events' history size.
* @throws Exception If failed.
*/
private void checkHistory(Ignite ignite, List<AffinityTopologyVersion> expHist, int expSize) throws Exception {
awaitPartitionMapExchange();
GridCacheProcessor proc = ((IgniteKernal) ignite).context().cache();
int cnt = 0;
for (GridCacheContext cctx : proc.context().cacheContexts()) {
GridAffinityAssignmentCache aff = GridTestUtils.getFieldValue(cctx.affinity(), "aff");
AtomicInteger histSize = GridTestUtils.getFieldValue(aff, "histSize");
assertEquals(expSize, histSize.get());
Map<AffinityTopologyVersion, Object> cache = GridTestUtils.getFieldValue(aff, "affCache");
assertEquals("Unexpected history: " + cache.keySet(), expHist.size(), cache.size());
for (AffinityTopologyVersion topVer : expHist) assertTrue("No history [ver=" + topVer + ", hist=" + cache.keySet() + ']', cache.containsKey(topVer));
cnt++;
}
assert cnt > 4;
}
Aggregations