use of org.apache.ignite.internal.processors.cache.GridCacheMapEntry in project ignite by apache.
the class TxOptimisticDeadlockDetectionTest method doTestDeadlock.
/**
* @throws Exception If failed.
*/
private void doTestDeadlock(final int txCnt, final boolean loc, boolean lockPrimaryFirst, final boolean clientTx, final IgniteClosure<Integer, Object> transformer) throws Exception {
log.info(">>> Test deadlock [txCnt=" + txCnt + ", loc=" + loc + ", lockPrimaryFirst=" + lockPrimaryFirst + ", clientTx=" + clientTx + ", transformer=" + transformer.getClass().getName() + ']');
TestCommunicationSpi.init(txCnt);
final AtomicInteger threadCnt = new AtomicInteger();
final CyclicBarrier barrier = new CyclicBarrier(txCnt);
final AtomicReference<TransactionDeadlockException> deadlockErr = new AtomicReference<>();
final List<List<Integer>> keySets = generateKeys(txCnt, loc, !lockPrimaryFirst);
final Set<Integer> involvedKeys = new GridConcurrentHashSet<>();
final Set<Integer> involvedLockedKeys = new GridConcurrentHashSet<>();
final Set<IgniteInternalTx> involvedTxs = new GridConcurrentHashSet<>();
IgniteInternalFuture<Long> fut = GridTestUtils.runMultiThreadedAsync(new Runnable() {
@Override
public void run() {
int threadNum = threadCnt.incrementAndGet();
Ignite ignite = loc ? ignite(0) : ignite(clientTx ? threadNum - 1 + txCnt : threadNum - 1);
IgniteCache<Object, Integer> cache = ignite.cache(CACHE_NAME);
List<Integer> keys = keySets.get(threadNum - 1);
int txTimeout = 500 + txCnt * 100;
try (Transaction tx = ignite.transactions().txStart(OPTIMISTIC, REPEATABLE_READ, txTimeout, 0)) {
IgniteInternalTx tx0 = ((TransactionProxyImpl) tx).tx();
involvedTxs.add(tx0);
Integer key = keys.get(0);
involvedKeys.add(key);
Object k;
log.info(">>> Performs put [node=" + ((IgniteKernal) ignite).localNode().id() + ", tx=" + tx.xid() + ", key=" + transformer.apply(key) + ']');
cache.put(transformer.apply(key), 0);
involvedLockedKeys.add(key);
barrier.await();
key = keys.get(1);
ClusterNode primaryNode = ((IgniteCacheProxy) cache).context().affinity().primaryByKey(key, NONE);
List<Integer> primaryKeys = primaryKeys(grid(primaryNode).cache(CACHE_NAME), 5, key + (100 * threadNum));
Map<Object, Integer> entries = new HashMap<>();
involvedKeys.add(key);
entries.put(transformer.apply(key), 0);
for (Integer i : primaryKeys) {
involvedKeys.add(i);
entries.put(transformer.apply(i), 1);
k = transformer.apply(i + 13);
involvedKeys.add(i + 13);
entries.put(k, 2);
}
log.info(">>> Performs put [node=" + ((IgniteKernal) ignite).localNode().id() + ", tx=" + tx.xid() + ", entries=" + entries + ']');
cache.putAll(entries);
tx.commit();
} catch (Throwable e) {
log.info("Expected exception: " + e);
e.printStackTrace(System.out);
// At least one stack trace should contain TransactionDeadlockException.
if (hasCause(e, TransactionTimeoutException.class) && hasCause(e, TransactionDeadlockException.class)) {
if (deadlockErr.compareAndSet(null, cause(e, TransactionDeadlockException.class))) {
log.info("At least one stack trace should contain " + TransactionDeadlockException.class.getSimpleName());
e.printStackTrace(System.out);
}
}
}
}
}, loc ? 2 : txCnt, "tx-thread");
try {
fut.get();
} catch (IgniteCheckedException e) {
U.error(null, "Unexpected exception", e);
fail();
}
U.sleep(1000);
TransactionDeadlockException deadlockE = deadlockErr.get();
assertNotNull("Failed to detect deadlock", deadlockE);
boolean fail = false;
// Check transactions, futures and entry locks state.
for (int i = 0; i < NODES_CNT * 2; i++) {
Ignite ignite = ignite(i);
int cacheId = ((IgniteCacheProxy) ignite.cache(CACHE_NAME)).context().cacheId();
GridCacheSharedContext<Object, Object> cctx = ((IgniteKernal) ignite).context().cache().context();
IgniteTxManager txMgr = cctx.tm();
Collection<IgniteInternalTx> activeTxs = txMgr.activeTransactions();
for (IgniteInternalTx tx : activeTxs) {
Collection<IgniteTxEntry> entries = tx.allEntries();
for (IgniteTxEntry entry : entries) {
if (entry.cacheId() == cacheId) {
fail = true;
U.error(log, "Transaction still exists: " + "\n" + tx.xidVersion() + "\n" + tx.nearXidVersion() + "\n nodeId=" + cctx.localNodeId() + "\n tx=" + tx);
}
}
}
Collection<IgniteInternalFuture<?>> futs = txMgr.deadlockDetectionFutures();
assertTrue(futs.isEmpty());
GridCacheAdapter<Object, Integer> intCache = internalCache(i, CACHE_NAME);
GridCacheConcurrentMap map = intCache.map();
for (Integer key : involvedKeys) {
Object key0 = transformer.apply(key);
KeyCacheObject keyCacheObj = intCache.context().toCacheKeyObject(key0);
GridCacheMapEntry entry = map.getEntry(keyCacheObj);
if (entry != null)
assertNull("Entry still has locks " + entry, entry.mvccAllLocal());
}
}
if (fail)
fail("Some transactions still exist");
// Check deadlock report
String msg = deadlockE.getMessage();
for (IgniteInternalTx tx : involvedTxs) assertTrue(msg.contains("[txId=" + tx.xidVersion() + ", nodeId=" + tx.nodeId() + ", threadId=" + tx.threadId() + ']'));
for (Integer key : involvedKeys) {
if (involvedLockedKeys.contains(key))
assertTrue(msg.contains("[key=" + transformer.apply(key) + ", cache=" + CACHE_NAME + ']'));
else
assertFalse(msg.contains("[key=" + transformer.apply(key)));
}
}
use of org.apache.ignite.internal.processors.cache.GridCacheMapEntry in project ignite by apache.
the class TxPessimisticDeadlockDetectionTest method doTestDeadlock.
/**
* @throws Exception If failed.
*/
private void doTestDeadlock(final int txCnt, final boolean loc, boolean lockPrimaryFirst, final boolean clientTx, final IgniteClosure<Integer, Object> transformer) throws Exception {
log.info(">>> Test deadlock [txCnt=" + txCnt + ", loc=" + loc + ", lockPrimaryFirst=" + lockPrimaryFirst + ", clientTx=" + clientTx + ", transformer=" + transformer.getClass().getName() + ']');
final AtomicInteger threadCnt = new AtomicInteger();
final CyclicBarrier barrier = new CyclicBarrier(txCnt);
final AtomicReference<TransactionDeadlockException> deadlockErr = new AtomicReference<>();
final List<List<Integer>> keySets = generateKeys(txCnt, loc, !lockPrimaryFirst);
final Set<Integer> involvedKeys = new GridConcurrentHashSet<>();
final Set<Integer> involvedLockedKeys = new GridConcurrentHashSet<>();
final Set<IgniteInternalTx> involvedTxs = new GridConcurrentHashSet<>();
IgniteInternalFuture<Long> fut = GridTestUtils.runMultiThreadedAsync(new Runnable() {
@Override
public void run() {
int threadNum = threadCnt.incrementAndGet();
Ignite ignite = loc ? ignite(0) : ignite(clientTx ? threadNum - 1 + txCnt : threadNum - 1);
IgniteCache<Object, Integer> cache = ignite.cache(CACHE_NAME);
List<Integer> keys = keySets.get(threadNum - 1);
int txTimeout = 500 + txCnt * 100;
try (Transaction tx = ignite.transactions().txStart(PESSIMISTIC, REPEATABLE_READ, txTimeout, 0)) {
involvedTxs.add(((TransactionProxyImpl) tx).tx());
Integer key = keys.get(0);
involvedKeys.add(key);
Object k;
log.info(">>> Performs put [node=" + ((IgniteKernal) ignite).localNode() + ", tx=" + tx + ", key=" + transformer.apply(key) + ']');
cache.put(transformer.apply(key), 0);
involvedLockedKeys.add(key);
barrier.await();
key = keys.get(1);
ClusterNode primaryNode = ((IgniteCacheProxy) cache).context().affinity().primaryByKey(key, NONE);
List<Integer> primaryKeys = primaryKeys(grid(primaryNode).cache(CACHE_NAME), 5, key + (100 * threadNum));
Map<Object, Integer> entries = new HashMap<>();
involvedKeys.add(key);
entries.put(transformer.apply(key), 0);
for (Integer i : primaryKeys) {
involvedKeys.add(i);
entries.put(transformer.apply(i), 1);
k = transformer.apply(i + 13);
involvedKeys.add(i + 13);
entries.put(k, 2);
}
log.info(">>> Performs put [node=" + ((IgniteKernal) ignite).localNode() + ", tx=" + tx + ", entries=" + entries + ']');
cache.putAll(entries);
tx.commit();
} catch (Throwable e) {
// At least one stack trace should contain TransactionDeadlockException.
if (hasCause(e, TransactionTimeoutException.class) && hasCause(e, TransactionDeadlockException.class)) {
if (deadlockErr.compareAndSet(null, cause(e, TransactionDeadlockException.class)))
U.error(log, "At least one stack trace should contain " + TransactionDeadlockException.class.getSimpleName(), e);
}
}
}
}, loc ? 2 : txCnt, "tx-thread");
try {
fut.get();
} catch (IgniteCheckedException e) {
U.error(null, "Unexpected exception", e);
fail();
}
U.sleep(1000);
TransactionDeadlockException deadlockE = deadlockErr.get();
assertNotNull(deadlockE);
boolean fail = false;
// Check transactions, futures and entry locks state.
for (int i = 0; i < NODES_CNT * 2; i++) {
Ignite ignite = ignite(i);
int cacheId = ((IgniteCacheProxy) ignite.cache(CACHE_NAME)).context().cacheId();
GridCacheSharedContext<Object, Object> cctx = ((IgniteKernal) ignite).context().cache().context();
IgniteTxManager txMgr = cctx.tm();
Collection<IgniteInternalTx> activeTxs = txMgr.activeTransactions();
for (IgniteInternalTx tx : activeTxs) {
Collection<IgniteTxEntry> entries = tx.allEntries();
for (IgniteTxEntry entry : entries) {
if (entry.cacheId() == cacheId) {
fail = true;
U.error(log, "Transaction still exists: " + "\n" + tx.xidVersion() + "\n" + tx.nearXidVersion() + "\n nodeId=" + cctx.localNodeId() + "\n tx=" + tx);
}
}
}
Collection<IgniteInternalFuture<?>> futs = txMgr.deadlockDetectionFutures();
assertTrue(futs.isEmpty());
GridCacheAdapter<Object, Integer> intCache = internalCache(i, CACHE_NAME);
GridCacheConcurrentMap map = intCache.map();
for (Integer key : involvedKeys) {
Object key0 = transformer.apply(key);
KeyCacheObject keyCacheObj = intCache.context().toCacheKeyObject(key0);
GridCacheMapEntry entry = map.getEntry(keyCacheObj);
if (entry != null)
assertNull("Entry still has locks " + entry, entry.mvccAllLocal());
}
}
if (fail)
fail("Some transactions still exist");
// Check deadlock report
String msg = deadlockE.getMessage();
for (IgniteInternalTx tx : involvedTxs) assertTrue(msg.contains("[txId=" + tx.xidVersion() + ", nodeId=" + tx.nodeId() + ", threadId=" + tx.threadId() + ']'));
for (Integer key : involvedKeys) {
if (involvedLockedKeys.contains(key))
assertTrue(msg.contains("[key=" + transformer.apply(key) + ", cache=" + CACHE_NAME + ']'));
else
assertFalse(msg.contains("[key=" + transformer.apply(key)));
}
}
use of org.apache.ignite.internal.processors.cache.GridCacheMapEntry in project ignite by apache.
the class GridCacheSetAbstractSelfTest method testCleanup.
/**
* @param collocated Collocation flag.
* @throws Exception If failed.
*/
@SuppressWarnings("WhileLoopReplaceableByForEach")
private void testCleanup(boolean collocated) throws Exception {
CollectionConfiguration colCfg = config(collocated);
final IgniteSet<Integer> set0 = grid(0).set(SET_NAME, colCfg);
assertNotNull(set0);
final Collection<Set<Integer>> sets = new ArrayList<>();
for (int i = 0; i < gridCount(); i++) {
IgniteSet<Integer> set = grid(i).set(SET_NAME, null);
assertNotNull(set);
sets.add(set);
}
Collection<Integer> items = new ArrayList<>(10_000);
for (int i = 0; i < 10_000; i++) items.add(i);
set0.addAll(items);
assertEquals(10_000, set0.size());
final AtomicBoolean stop = new AtomicBoolean();
final AtomicInteger val = new AtomicInteger(10_000);
IgniteInternalFuture<?> fut;
try {
fut = GridTestUtils.runMultiThreadedAsync(new Callable<Object>() {
@Override
public Object call() throws Exception {
try {
while (!stop.get()) {
for (Set<Integer> set : sets) set.add(val.incrementAndGet());
}
} catch (IllegalStateException e) {
log.info("Set removed: " + e);
}
return null;
}
}, 5, "set-add-thread");
set0.close();
} finally {
stop.set(true);
}
fut.get();
int cnt = 0;
GridCacheContext cctx = GridTestUtils.getFieldValue(set0, "cctx");
for (int i = 0; i < gridCount(); i++) {
Iterator<GridCacheMapEntry> entries = (grid(i)).context().cache().internalCache(cctx.name()).map().entries().iterator();
while (entries.hasNext()) {
GridCacheEntryEx entry = entries.next();
if (entry.hasValue()) {
cnt++;
log.info("Unexpected entry: " + entry);
}
}
}
assertEquals("Found unexpected cache entries", 0, cnt);
for (final Set<Integer> set : sets) {
GridTestUtils.assertThrows(log, new Callable<Void>() {
@Override
public Void call() throws Exception {
set.add(10);
return null;
}
}, IllegalStateException.class, null);
}
}
use of org.apache.ignite.internal.processors.cache.GridCacheMapEntry in project ignite by apache.
the class GridCacheSetFailoverAbstractSelfTest method testNodeRestart.
/**
* @throws Exception If failed.
*/
@SuppressWarnings("WhileLoopReplaceableByForEach")
public void testNodeRestart() throws Exception {
IgniteSet<Integer> set = grid(0).set(SET_NAME, config(false));
final int ITEMS = 10_000;
Collection<Integer> items = new ArrayList<>(ITEMS);
for (int i = 0; i < ITEMS; i++) items.add(i);
set.addAll(items);
assertEquals(ITEMS, set.size());
AtomicBoolean stop = new AtomicBoolean();
IgniteInternalFuture<?> killFut = startNodeKiller(stop);
long stopTime = System.currentTimeMillis() + TEST_DURATION;
try {
ThreadLocalRandom rnd = ThreadLocalRandom.current();
while (System.currentTimeMillis() < stopTime) {
for (int i = 0; i < 10; i++) {
try {
int size = set.size();
// TODO: IGNITE-584, check for equality when IGNITE-584 fixed.
assertTrue(size > 0);
} catch (IgniteException ignore) {
// No-op.
}
try {
Iterator<Integer> iter = set.iterator();
int cnt = 0;
while (iter.hasNext()) {
assertNotNull(iter.next());
cnt++;
}
// TODO: IGNITE-584, check for equality when IGNITE-584 fixed.
assertTrue(cnt > 0);
} catch (IgniteException ignore) {
// No-op.
}
int val = rnd.nextInt(ITEMS);
assertTrue("Not contains: " + val, set.contains(val));
val = ITEMS + rnd.nextInt(ITEMS);
assertFalse("Contains: " + val, set.contains(val));
}
log.info("Remove set.");
set.close();
log.info("Create new set.");
set = grid(0).set(SET_NAME, config(false));
set.addAll(items);
}
} finally {
stop.set(true);
}
killFut.get();
set.close();
if (false) {
// TODO IGNITE-600: enable check when fixed.
int cnt = 0;
Set<IgniteUuid> setIds = new HashSet<>();
for (int i = 0; i < gridCount(); i++) {
Iterator<GridCacheMapEntry> entries = grid(i).context().cache().internalCache(DEFAULT_CACHE_NAME).map().entries().iterator();
while (entries.hasNext()) {
GridCacheEntryEx entry = entries.next();
if (entry.hasValue()) {
cnt++;
if (entry.key() instanceof SetItemKey) {
SetItemKey setItem = (SetItemKey) entry.key();
if (setIds.add(setItem.setId()))
log.info("Unexpected set item [setId=" + setItem.setId() + ", grid: " + grid(i).name() + ", entry=" + entry + ']');
}
}
}
}
assertEquals("Found unexpected cache entries", 0, cnt);
}
}
use of org.apache.ignite.internal.processors.cache.GridCacheMapEntry in project ignite by apache.
the class GridHashMapLoadTest method testMapEntry.
/**
* @throws Exception If failed.
*/
public void testMapEntry() throws Exception {
Map<Integer, GridCacheMapEntry> map = new HashMap<>(5 * 1024 * 1024);
int i = 0;
GridCacheTestContext<Integer, Integer> ctx = new GridCacheTestContext<>(new GridTestKernalContext(new GridTestLog4jLogger()));
while (true) {
Integer key = i++;
map.put(key, new GridCacheMapEntry(ctx, ctx.toCacheKeyObject(key)) {
@Override
public boolean tmLock(IgniteInternalTx tx, long timeout, @Nullable GridCacheVersion serOrder, GridCacheVersion serReadVer, boolean read) {
return false;
}
@Override
protected void checkThreadChain(GridCacheMvccCandidate owner) {
// No-op.
}
@Override
public void txUnlock(IgniteInternalTx tx) {
// No-op.
}
@Override
public boolean removeLock(GridCacheVersion ver) {
return false;
}
});
if (i % 100000 == 0)
info("Inserted objects: " + i / 2);
}
}
Aggregations