use of org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtInvalidPartitionException in project ignite by apache.
the class GridCacheUtils method createBackupPostProcessingClosure.
/**
* Creates closure that saves initial value to backup partition.
* <p>
* Useful only when store with readThrough is used. In situation when
* get() on backup node returns successful result, it's expected that
* localPeek() will be successful as well. But it isn't true when
* primary node loaded value from local store, in this case backups
* will remain non-initialized.
* <br>
* To meet that requirement the value requested from primary should
* be saved on backup during get().
* </p>
*
* @param topVer Topology version.
* @param log Logger.
* @param cctx Cache context.
* @param key Key.
* @param expiryPlc Expiry policy.
* @param readThrough Read through.
* @param skipVals Skip values.
*/
@Nullable
public static BackupPostProcessingClosure createBackupPostProcessingClosure(final AffinityTopologyVersion topVer, final IgniteLogger log, final GridCacheContext cctx, @Nullable final KeyCacheObject key, @Nullable final IgniteCacheExpiryPolicy expiryPlc, boolean readThrough, boolean skipVals) {
if (cctx.mvccEnabled() || !readThrough || skipVals || (key != null && !cctx.affinity().backupsByKey(key, topVer).contains(cctx.localNode())))
return null;
return new BackupPostProcessingClosure() {
private void process(KeyCacheObject key, CacheObject val, GridCacheVersion ver, GridDhtCacheAdapter colocated) {
while (true) {
GridCacheEntryEx entry = null;
cctx.shared().database().checkpointReadLock();
try {
entry = colocated.entryEx(key, topVer);
entry.initialValue(val, ver, expiryPlc == null ? 0 : expiryPlc.forCreate(), expiryPlc == null ? 0 : toExpireTime(expiryPlc.forCreate()), true, topVer, GridDrType.DR_BACKUP, true, false);
break;
} catch (GridCacheEntryRemovedException ignore) {
if (log.isDebugEnabled())
log.debug("Got removed entry during postprocessing (will retry): " + entry);
} catch (IgniteCheckedException e) {
U.error(log, "Error saving backup value: " + entry, e);
throw new GridClosureException(e);
} catch (GridDhtInvalidPartitionException ignored) {
break;
} finally {
if (entry != null)
entry.touch();
cctx.shared().database().checkpointReadUnlock();
}
}
}
@Override
public void apply(CacheObject val, GridCacheVersion ver) {
process(key, val, ver, cctx.dht());
}
@Override
public void apply(Collection<GridCacheEntryInfo> infos) {
if (!F.isEmpty(infos)) {
GridCacheAffinityManager aff = cctx.affinity();
ClusterNode locNode = cctx.localNode();
GridDhtCacheAdapter colocated = cctx.cache().isNear() ? ((GridNearCacheAdapter) cctx.cache()).dht() : cctx.dht();
for (GridCacheEntryInfo info : infos) {
// Save backup value.
if (aff.backupsByKey(info.key(), topVer).contains(locNode))
process(info.key(), info.value(), info.version(), colocated);
}
}
}
};
}
use of org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtInvalidPartitionException in project ignite by apache.
the class IgniteCacheOffheapManagerImpl method clearCache.
/**
* Clears offheap entries.
*
* @param readers {@code True} to clear readers.
*/
@Override
public void clearCache(GridCacheContext cctx, boolean readers) {
GridCacheVersion obsoleteVer = null;
try (GridCloseableIterator<CacheDataRow> it = grp.isLocal() ? iterator(cctx.cacheId(), cacheDataStores().iterator(), null, null) : evictionSafeIterator(cctx.cacheId(), cacheDataStores().iterator())) {
while (it.hasNext()) {
cctx.shared().database().checkpointReadLock();
try {
KeyCacheObject key = it.next().key();
try {
if (obsoleteVer == null)
obsoleteVer = cctx.cache().nextVersion();
GridCacheEntryEx entry = cctx.cache().entryEx(key);
entry.clear(obsoleteVer, readers);
} catch (GridDhtInvalidPartitionException ignore) {
// Ignore.
} catch (IgniteCheckedException e) {
U.error(log, "Failed to clear cache entry: " + key, e);
}
} finally {
cctx.shared().database().checkpointReadUnlock();
}
}
} catch (IgniteCheckedException e) {
U.error(log, "Failed to close iterator", e);
}
}
use of org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtInvalidPartitionException in project ignite by apache.
the class GridNearAtomicCache method processNearAtomicUpdateResponse.
/**
* @param ver Version.
* @param key Key.
* @param val Value.
* @param ttl TTL.
* @param expireTime Expire time.
* @param nodeId Node ID.
* @param taskName Task name.
* @param transformedValue {@code True} if transformed value.
* @throws IgniteCheckedException If failed.
*/
private void processNearAtomicUpdateResponse(GridCacheVersion ver, KeyCacheObject key, @Nullable CacheObject val, long ttl, long expireTime, boolean keepBinary, UUID nodeId, String taskName, boolean transformedValue) throws IgniteCheckedException {
try {
while (true) {
GridCacheEntryEx entry = null;
AffinityTopologyVersion topVer = ctx.affinity().affinityTopologyVersion();
try {
entry = entryEx(key, topVer);
GridCacheOperation op = val != null ? UPDATE : DELETE;
GridCacheUpdateAtomicResult updRes = entry.innerUpdate(ver, nodeId, nodeId, op, val, null, /*write-through*/
false, /*read-through*/
false, /*retval*/
false, keepBinary, /*expiry policy*/
null, /*event*/
true, /*metrics*/
true, /*primary*/
false, /*check version*/
true, topVer, CU.empty0(), DR_NONE, ttl, expireTime, null, false, false, taskName, null, null, null, transformedValue);
if (updRes.removeVersion() != null)
ctx.onDeferredDelete(entry, updRes.removeVersion());
// While.
break;
} catch (GridCacheEntryRemovedException ignored) {
if (log.isDebugEnabled())
log.debug("Got removed entry while updating near cache value (will retry): " + key);
entry = null;
} finally {
if (entry != null)
entry.touch();
}
}
} catch (GridDhtInvalidPartitionException ignored) {
// Ignore.
}
}
use of org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtInvalidPartitionException in project ignite by apache.
the class GridNearGetFuture method localDhtGet.
/**
* @param key Key.
* @param part Partition.
* @param topVer Topology version.
* @param nearRead {@code True} if already tried to read from near cache.
* @return {@code True} if there is no need to further search value.
*/
private boolean localDhtGet(KeyCacheObject key, int part, AffinityTopologyVersion topVer, boolean nearRead) {
GridDhtCacheAdapter<K, V> dht = cache().dht();
assert dht.context().affinityNode() : this;
while (true) {
cctx.shared().database().checkpointReadLock();
GridCacheEntryEx dhtEntry = null;
try {
dhtEntry = dht.entryEx(key);
CacheObject v = null;
// If near cache does not have value, then we peek DHT cache.
if (dhtEntry != null) {
boolean isNew = dhtEntry.isNewLocked() || !dhtEntry.valid(topVer);
if (needVer) {
EntryGetResult res = dhtEntry.innerGetVersioned(null, null, /*update-metrics*/
false, /*event*/
!nearRead && !skipVals, null, taskName, expiryPlc, !deserializeBinary, null);
if (res != null) {
v = res.value();
ver = res.version();
}
} else {
v = dhtEntry.innerGet(null, tx, /*read-through*/
false, /*update-metrics*/
false, /*events*/
!nearRead && !skipVals, null, taskName, expiryPlc, !deserializeBinary);
}
// Entry was not in memory or in swap, so we remove it from cache.
if (v == null && isNew && dhtEntry.markObsoleteIfEmpty(ver))
dht.removeEntry(dhtEntry);
}
if (v != null) {
if (cctx.statisticsEnabled() && !skipVals)
cache().metrics0().onRead(true);
addResult(key, v, ver);
return true;
} else {
boolean topStable = cctx.isReplicated() || topVer.equals(cctx.topology().lastTopologyChangeVersion());
// Entry not found, do not continue search if topology did not change and there is no store.
return !cctx.readThroughConfigured() && (topStable || partitionOwned(part));
}
} catch (GridCacheEntryRemovedException ignored) {
// Retry.
} catch (GridDhtInvalidPartitionException ignored) {
return false;
} catch (IgniteCheckedException e) {
onDone(e);
return false;
} finally {
cctx.shared().database().checkpointReadUnlock();
if (dhtEntry != null)
// Near cache is enabled, so near entry will be enlisted in the transaction.
// Always touch DHT entry in this case.
dhtEntry.touch();
}
}
}
use of org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtInvalidPartitionException in project ignite by apache.
the class GridCacheAtomicInvalidPartitionHandlingSelfTest method checkRestarts.
/**
* @param writeSync Write synchronization mode to check.
* @throws Exception If failed.
*/
private void checkRestarts(CacheWriteSynchronizationMode writeSync) throws Exception {
this.writeSync = writeSync;
final int gridCnt = 6;
startGrids(gridCnt);
awaitPartitionMapExchange();
try {
assertEquals(testClientNode(), (boolean) grid(0).configuration().isClientMode());
final IgniteCache<Object, Object> cache = grid(0).cache(DEFAULT_CACHE_NAME);
final int range = 10_000;
final Set<Integer> keys = new LinkedHashSet<>();
try (IgniteDataStreamer<Integer, Integer> streamer = grid(0).dataStreamer(DEFAULT_CACHE_NAME)) {
streamer.allowOverwrite(true);
for (int i = 0; i < range; i++) {
streamer.addData(i, 0);
keys.add(i);
if (i > 0 && i % 10_000 == 0)
System.err.println("Put: " + i);
}
}
final Affinity<Integer> aff = grid(0).affinity(DEFAULT_CACHE_NAME);
boolean putDone = GridTestUtils.waitForCondition(new GridAbsPredicate() {
@Override
public boolean apply() {
Iterator<Integer> it = keys.iterator();
while (it.hasNext()) {
Integer key = it.next();
Collection<ClusterNode> affNodes = aff.mapKeyToPrimaryAndBackups(key);
for (int i = 0; i < gridCnt; i++) {
ClusterNode locNode = grid(i).localNode();
IgniteCache<Object, Object> cache = grid(i).cache(DEFAULT_CACHE_NAME);
Object val = cache.localPeek(key);
if (affNodes.contains(locNode)) {
if (val == null)
return false;
} else
assertNull(val);
}
it.remove();
}
return true;
}
}, 30_000);
assertTrue(putDone);
assertTrue(keys.isEmpty());
final AtomicBoolean done = new AtomicBoolean();
delay = true;
System.err.println("FINISHED PUTS");
// Start put threads.
IgniteInternalFuture<?> fut = multithreadedAsync(new Callable<Object>() {
@Override
public Object call() throws Exception {
Random rnd = new Random();
while (!done.get()) {
try {
int cnt = rnd.nextInt(5);
if (cnt < 2) {
int key = rnd.nextInt(range);
int val = rnd.nextInt();
cache.put(key, val);
} else {
Map<Integer, Integer> upd = new TreeMap<>();
for (int i = 0; i < cnt; i++) upd.put(rnd.nextInt(range), rnd.nextInt());
cache.putAll(upd);
}
} catch (CachePartialUpdateException ignored) {
// No-op.
}
}
return null;
}
}, 4, "putAll-thread");
Random rnd = new Random();
// Restart random nodes.
for (int r = 0; r < 10; r++) {
int idx0 = rnd.nextInt(gridCnt - 1) + 1;
stopGrid(idx0);
U.sleep(200);
startGrid(idx0);
}
done.set(true);
awaitPartitionMapExchange();
fut.get();
for (int k = 0; k < range; k++) {
Collection<ClusterNode> affNodes = affinity(cache).mapKeyToPrimaryAndBackups(k);
// Test is valid with at least one backup.
assert affNodes.size() >= 2;
Object val = null;
GridCacheVersion ver = null;
UUID nodeId = null;
for (int i = 0; i < gridCnt; i++) {
ClusterNode locNode = grid(i).localNode();
GridCacheAdapter<Object, Object> c = ((IgniteKernal) grid(i)).internalCache(DEFAULT_CACHE_NAME);
GridCacheEntryEx entry = null;
try {
entry = c.entryEx(k);
entry.unswap();
} catch (GridDhtInvalidPartitionException ignored) {
// Skip key.
}
for (int r = 0; r < 10; r++) {
try {
if (affNodes.contains(locNode)) {
assert c.affinity().isPrimaryOrBackup(locNode, k);
boolean primary = c.affinity().isPrimary(locNode, k);
assertNotNull("Failed to find entry on node for key [locNode=" + locNode.id() + ", key=" + k + ']', entry);
if (val == null) {
assertNull(ver);
val = CU.value(entry.rawGet(), entry.context(), false);
ver = entry.version();
nodeId = locNode.id();
} else {
assertNotNull(ver);
assertEquals("Failed to check value for key [key=" + k + ", node=" + locNode.id() + ", primary=" + primary + ", recNodeId=" + nodeId + ']', val, CU.value(entry.rawGet(), entry.context(), false));
assertEquals("Failed to check version for key [key=" + k + ", node=" + locNode.id() + ", primary=" + primary + ", recNodeId=" + nodeId + ']', ver, entry.version());
}
} else
assertTrue("Invalid entry: " + entry, entry == null || !entry.partitionValid());
} catch (AssertionError e) {
if (r == 9) {
info("Failed to verify cache contents: " + e.getMessage());
throw e;
}
info("Failed to verify cache contents, will retry: " + e.getMessage());
// Give some time to finish async updates.
U.sleep(1000);
}
}
}
}
} finally {
stopAllGrids();
}
}
Aggregations