use of org.apache.ignite.internal.processors.cache.GridCacheEntryInfo in project ignite by apache.
the class GridDhtPartitionDemander method handleSupplyMessage.
/**
* @param idx Index.
* @param id Node id.
* @param supply Supply.
*/
public void handleSupplyMessage(int idx, final UUID id, final GridDhtPartitionSupplyMessage supply) {
AffinityTopologyVersion topVer = supply.topologyVersion();
final RebalanceFuture fut = rebalanceFut;
ClusterNode node = cctx.node(id);
if (node == null)
return;
if (// Current future have another update sequence.
!fut.isActual(supply.updateSequence()))
// Supple message based on another future.
return;
if (// Topology already changed (for the future that supply message based on).
topologyChanged(fut))
return;
if (log.isDebugEnabled())
log.debug("Received supply message: " + supply);
// Check whether there were class loading errors on unmarshal
if (supply.classError() != null) {
U.warn(log, "Rebalancing from node cancelled [node=" + id + "]. Class got undeployed during preloading: " + supply.classError());
fut.cancel(id);
return;
}
final GridDhtPartitionTopology top = cctx.dht().topology();
try {
// Preload.
for (Map.Entry<Integer, CacheEntryInfoCollection> e : supply.infos().entrySet()) {
int p = e.getKey();
if (cctx.affinity().partitionLocalNode(p, topVer)) {
GridDhtLocalPartition part = top.localPartition(p, topVer, true);
assert part != null;
boolean last = supply.last().contains(p);
if (part.state() == MOVING) {
boolean reserved = part.reserve();
assert reserved : "Failed to reserve partition [igniteInstanceName=" + cctx.igniteInstanceName() + ", cacheName=" + cctx.name() + ", part=" + part + ']';
part.lock();
try {
// Loop through all received entries and try to preload them.
for (GridCacheEntryInfo entry : e.getValue().infos()) {
if (!part.preloadingPermitted(entry.key(), entry.version())) {
if (log.isDebugEnabled())
log.debug("Preloading is not permitted for entry due to " + "evictions [key=" + entry.key() + ", ver=" + entry.version() + ']');
continue;
}
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;
}
}
// then we take ownership.
if (last) {
top.own(part);
fut.partitionDone(id, p);
if (log.isDebugEnabled())
log.debug("Finished rebalancing partition: " + part);
}
} finally {
part.unlock();
part.release();
}
} else {
if (last)
fut.partitionDone(id, p);
if (log.isDebugEnabled())
log.debug("Skipping rebalancing partition (state is not MOVING): " + part);
}
} else {
fut.partitionDone(id, 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 (cctx.affinity().partitionLocalNode(miss, topVer))
fut.partitionMissed(id, miss);
}
for (Integer miss : supply.missed()) fut.partitionDone(id, miss);
GridDhtPartitionDemandMessage d = new GridDhtPartitionDemandMessage(supply.updateSequence(), supply.topologyVersion(), cctx.cacheId());
d.timeout(cctx.config().getRebalanceTimeout());
d.topic(rebalanceTopics.get(idx));
if (!topologyChanged(fut) && !fut.isDone()) {
// Send demand message.
cctx.io().sendOrderedMessage(node, rebalanceTopics.get(idx), d, cctx.ioPolicy(), cctx.config().getRebalanceTimeout());
}
} catch (IgniteCheckedException e) {
if (log.isDebugEnabled())
log.debug("Node left during rebalancing [node=" + node.id() + ", msg=" + e.getMessage() + ']');
} catch (IgniteSpiException e) {
if (log.isDebugEnabled())
log.debug("Failed to send message to node (current node is stopping?) [node=" + node.id() + ", msg=" + e.getMessage() + ']');
}
}
use of org.apache.ignite.internal.processors.cache.GridCacheEntryInfo in project ignite by apache.
the class GridNearGetFuture method loadEntries.
/**
* @param nodeId Node id.
* @param keys Keys.
* @param infos Entry infos.
* @param savedEntries Saved entries.
* @param topVer Topology version
* @return Result map.
*/
private Map<K, V> loadEntries(UUID nodeId, Collection<KeyCacheObject> keys, Collection<GridCacheEntryInfo> infos, Map<KeyCacheObject, GridNearCacheEntry> savedEntries, AffinityTopologyVersion topVer) {
boolean empty = F.isEmpty(keys);
Map<K, V> map = empty ? Collections.<K, V>emptyMap() : new GridLeanMap<K, V>(keys.size());
if (!empty) {
boolean atomic = cctx.atomic();
GridCacheVersion ver = atomic ? null : F.isEmpty(infos) ? null : cctx.versions().next();
for (GridCacheEntryInfo info : infos) {
try {
info.unmarshalValue(cctx, cctx.deploy().globalLoader());
// Entries available locally in DHT should not be loaded into near cache for reading.
if (!cctx.affinity().keyLocalNode(info.key(), cctx.affinity().affinityTopologyVersion())) {
GridNearCacheEntry entry = savedEntries.get(info.key());
if (entry == null)
entry = cache().entryExx(info.key(), topVer);
// Load entry into cache.
entry.loadedValue(tx, nodeId, info.value(), atomic ? info.version() : ver, info.version(), info.ttl(), info.expireTime(), true, !deserializeBinary, topVer, subjId);
}
CacheObject val = info.value();
KeyCacheObject key = info.key();
assert skipVals == (info.value() == null);
cctx.addResult(map, key, val, skipVals, keepCacheObjects, deserializeBinary, false, needVer ? info.version() : null, 0, 0);
} catch (GridCacheEntryRemovedException ignore) {
if (log.isDebugEnabled())
log.debug("Got removed entry while processing get response (will not retry).");
} catch (Exception e) {
// Fail.
onDone(e);
return Collections.emptyMap();
}
}
}
return map;
}
use of org.apache.ignite.internal.processors.cache.GridCacheEntryInfo in project ignite by apache.
the class GridNearGetResponse method prepareMarshal.
/** {@inheritDoc}
* @param ctx*/
@Override
public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException {
super.prepareMarshal(ctx);
GridCacheContext cctx = ctx.cacheContext(cacheId);
if (entries != null) {
for (GridCacheEntryInfo info : entries) info.marshal(cctx);
}
if (err != null && errBytes == null)
errBytes = U.marshal(ctx, err);
}
use of org.apache.ignite.internal.processors.cache.GridCacheEntryInfo in project ignite by apache.
the class GridNearGetFuture method map.
/**
* @param keys Keys.
* @param mapped Mappings to check for duplicates.
* @param topVer Topology version to map on.
*/
private void map(Collection<KeyCacheObject> keys, Map<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> mapped, final AffinityTopologyVersion topVer) {
Collection<ClusterNode> affNodes = CU.affinityNodes(cctx, topVer);
if (affNodes.isEmpty()) {
assert !cctx.affinityNode();
onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for near-only cache (all partition " + "nodes left the grid)."));
return;
}
Map<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> mappings = U.newHashMap(affNodes.size());
Map<KeyCacheObject, GridNearCacheEntry> savedEntries = null;
{
boolean success = false;
try {
// Assign keys to primary nodes.
for (KeyCacheObject key : keys) savedEntries = map(key, mappings, topVer, mapped, savedEntries);
success = true;
} finally {
// Exception has been thrown, must release reserved near entries.
if (!success) {
GridCacheVersion obsolete = cctx.versions().next(topVer);
if (savedEntries != null) {
for (GridNearCacheEntry reserved : savedEntries.values()) {
reserved.releaseEviction();
if (reserved.markObsolete(obsolete))
reserved.context().cache().removeEntry(reserved);
}
}
}
}
}
if (isDone())
return;
final Map<KeyCacheObject, GridNearCacheEntry> saved = savedEntries != null ? savedEntries : Collections.<KeyCacheObject, GridNearCacheEntry>emptyMap();
final int keysSize = keys.size();
// Create mini futures.
for (Map.Entry<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> entry : mappings.entrySet()) {
final ClusterNode n = entry.getKey();
final LinkedHashMap<KeyCacheObject, Boolean> mappedKeys = entry.getValue();
assert !mappedKeys.isEmpty();
// If this is the primary or backup node for the keys.
if (n.isLocal()) {
final GridDhtFuture<Collection<GridCacheEntryInfo>> fut = dht().getDhtAsync(n.id(), -1, mappedKeys, readThrough, topVer, subjId, taskName == null ? 0 : taskName.hashCode(), expiryPlc, skipVals, recovery);
final Collection<Integer> invalidParts = fut.invalidPartitions();
if (!F.isEmpty(invalidParts)) {
Collection<KeyCacheObject> remapKeys = new ArrayList<>(keysSize);
for (KeyCacheObject key : keys) {
if (key != null && invalidParts.contains(cctx.affinity().partition(key)))
remapKeys.add(key);
}
AffinityTopologyVersion updTopVer = cctx.discovery().topologyVersionEx();
assert updTopVer.compareTo(topVer) > 0 : "Got invalid partitions for local node but topology version did " + "not change [topVer=" + topVer + ", updTopVer=" + updTopVer + ", invalidParts=" + invalidParts + ']';
// Remap recursively.
map(remapKeys, mappings, updTopVer);
}
// Add new future.
add(fut.chain(new C1<IgniteInternalFuture<Collection<GridCacheEntryInfo>>, Map<K, V>>() {
@Override
public Map<K, V> apply(IgniteInternalFuture<Collection<GridCacheEntryInfo>> fut) {
try {
return loadEntries(n.id(), mappedKeys.keySet(), fut.get(), saved, topVer);
} catch (Exception e) {
U.error(log, "Failed to get values from dht cache [fut=" + fut + "]", e);
onDone(e);
return Collections.emptyMap();
}
}
}));
} else {
if (!trackable) {
trackable = true;
cctx.mvcc().addFuture(this, futId);
}
MiniFuture fut = new MiniFuture(n, mappedKeys, saved, topVer);
GridCacheMessage req = new GridNearGetRequest(cctx.cacheId(), futId, fut.futureId(), ver, mappedKeys, readThrough, topVer, subjId, taskName == null ? 0 : taskName.hashCode(), expiryPlc != null ? expiryPlc.forCreate() : -1L, expiryPlc != null ? expiryPlc.forAccess() : -1L, skipVals, cctx.deploymentEnabled(), recovery);
// Append new future.
add(fut);
try {
cctx.io().send(n, req, cctx.ioPolicy());
} catch (IgniteCheckedException e) {
// Fail the whole thing.
if (e instanceof ClusterTopologyCheckedException)
fut.onNodeLeft();
else
fut.onResult(e);
}
}
}
}
use of org.apache.ignite.internal.processors.cache.GridCacheEntryInfo in project ignite by apache.
the class GridNearGetResponse method finishUnmarshal.
/** {@inheritDoc} */
@Override
public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException {
super.finishUnmarshal(ctx, ldr);
GridCacheContext cctx = ctx.cacheContext(cacheId());
if (entries != null) {
for (GridCacheEntryInfo info : entries) info.unmarshal(cctx, ldr);
}
if (errBytes != null && err == null)
err = U.unmarshal(ctx, errBytes, U.resolveClassLoader(ldr, ctx.gridConfig()));
}
Aggregations