/** * In ATOMIC cache with CLOCK mode if key is updated from different nodes at same time only one * update wins others are ignored (can happen in test event when updates are executed from * different nodes sequentially), this delay is used to avoid lost updates. * * @param cache Cache. * @throws Exception If failed. */ protected void atomicClockModeDelay(IgniteCache cache) throws Exception { CacheConfiguration ccfg = (CacheConfiguration) cache.getConfiguration(CacheConfiguration.class); if (ccfg.getCacheMode() != LOCAL && ccfg.getAtomicityMode() == CacheAtomicityMode.ATOMIC && ccfg.getAtomicWriteOrderMode() == CacheAtomicWriteOrderMode.CLOCK) U.sleep(50); }
/** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override public boolean addAll(final Collection<? extends T> items) { A.notNull(items, "items"); try { boolean retVal; int cnt = 0; while (true) { try (IgniteInternalTx tx = cache.txStartEx(PESSIMISTIC, REPEATABLE_READ)) { Long idx = (Long) cache.invoke(queueKey, new AddProcessor(id, items.size())).get(); if (idx != null) { checkRemoved(idx); Map<GridCacheQueueItemKey, T> putMap = new HashMap<>(); for (T item : items) { putMap.put(itemKey(idx), item); idx++; } cache.putAll(putMap); retVal = true; } else retVal = false; tx.commit(); break; } catch (ClusterTopologyCheckedException e) { if (e instanceof ClusterGroupEmptyCheckedException) throw e; if (cnt++ == MAX_UPDATE_RETRIES) throw e; else { U.warn(log, "Failed to add item, will retry [err=" + e + ']'); U.sleep(RETRY_DELAY); } } } return retVal; } catch (IgniteCheckedException e) { throw U.convertException(e); } }
/** @throws Exception If any error occurs. */ public void testMultipleStartOnCoordinatorStop() throws Exception { for (int k = 0; k < 3; k++) { log.info("Iteration: " + k); clientFlagGlobal = false; final int START_NODES = 5; final int JOIN_NODES = 10; startGrids(START_NODES); final CyclicBarrier barrier = new CyclicBarrier(JOIN_NODES + 1); final AtomicInteger startIdx = new AtomicInteger(START_NODES); IgniteInternalFuture<?> fut = GridTestUtils.runMultiThreadedAsync( new Callable<Object>() { @Override public Object call() throws Exception { int idx = startIdx.getAndIncrement(); Thread.currentThread().setName("start-thread-" + idx); barrier.await(); Ignite ignite = startGrid(idx); assertFalse(ignite.configuration().isClientMode()); log.info("Started node: " + ignite.name()); return null; } }, JOIN_NODES, "start-thread"); barrier.await(); U.sleep(ThreadLocalRandom.current().nextInt(10, 100)); for (int i = 0; i < START_NODES; i++) stopGrid(i); fut.get(); stopAllGrids(); } }
/** * Checks that cache is empty. * * @param cache Cache to check. * @throws org.apache.ignite.internal.IgniteInterruptedCheckedException If interrupted while * sleeping. */ @SuppressWarnings({"ErrorNotRethrown", "TypeMayBeWeakened"}) private void checkEmpty(IgniteCache<String, String> cache) throws IgniteInterruptedCheckedException { for (int i = 0; i < 3; i++) { try { assertTrue(!cache.iterator().hasNext()); break; } catch (AssertionError e) { if (i == 2) throw e; info(">>> Cache is not empty, flushing evictions."); U.sleep(1000); } } }
/** * Executes command using {@code shell} channel. * * @param ses SSH session. * @param cmd Command. * @throws JSchException In case of SSH error. * @throws IOException If IO error occurs. * @throws IgniteInterruptedCheckedException If thread was interrupted while waiting. */ private void shell(Session ses, String cmd) throws JSchException, IOException, IgniteInterruptedCheckedException { ChannelShell ch = null; try { ch = (ChannelShell) ses.openChannel("shell"); ch.connect(); try (PrintStream out = new PrintStream(ch.getOutputStream(), true)) { out.println(cmd); U.sleep(1000); } } finally { if (ch != null && ch.isConnected()) ch.disconnect(); } }
/** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override public boolean offer(final T item) throws IgniteException { A.notNull(item, "item"); try { boolean retVal; int cnt = 0; while (true) { try { try (IgniteInternalTx tx = cache.txStartEx(PESSIMISTIC, REPEATABLE_READ)) { Long idx = (Long) cache.invoke(queueKey, new AddProcessor(id, 1)).get(); if (idx != null) { checkRemoved(idx); cache.getAndPut(itemKey(idx), item); retVal = true; } else retVal = false; tx.commit(); break; } } catch (ClusterTopologyCheckedException e) { if (e instanceof ClusterGroupEmptyCheckedException) throw e; if (cnt++ == MAX_UPDATE_RETRIES) throw e; else { U.warn(log, "Failed to add item, will retry [err=" + e + ']'); U.sleep(RETRY_DELAY); } } } return retVal; } catch (IgniteCheckedException e) { throw U.convertException(e); } }
/** * Calls garbage collector and wait. * * @throws Exception if any thread has interrupted the current thread while waiting. */ private void gc() throws Exception { Runtime rt = Runtime.getRuntime(); long freeMem0 = rt.freeMemory(); long freeMem = Long.MAX_VALUE; int cnt = 0; while (freeMem0 < freeMem && cnt < GC_CALL_CNT) { System.gc(); U.sleep(WAIT_TIME); cnt++; freeMem = freeMem0; freeMem0 = rt.freeMemory(); } }
/** {@inheritDoc} */ @SuppressWarnings("unchecked") @Nullable @Override public T poll() throws IgniteException { try { int cnt = 0; T retVal; while (true) { try (IgniteInternalTx tx = cache.txStartEx(PESSIMISTIC, REPEATABLE_READ)) { Long idx = (Long) cache.invoke(queueKey, new PollProcessor(id)).get(); if (idx != null) { checkRemoved(idx); retVal = (T) cache.getAndRemove(itemKey(idx)); assert retVal != null : idx; } else retVal = null; tx.commit(); break; } catch (ClusterTopologyCheckedException e) { if (e instanceof ClusterGroupEmptyCheckedException) throw e; if (cnt++ == MAX_UPDATE_RETRIES) throw e; else { U.warn(log, "Failed to add item, will retry [err=" + e + ']'); U.sleep(RETRY_DELAY); } } } return retVal; } catch (IgniteCheckedException e) { throw U.convertException(e); } }
/** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override protected void removeItem(final long rmvIdx) throws IgniteCheckedException { try { int cnt = 0; while (true) { try (IgniteInternalTx tx = cache.txStartEx(PESSIMISTIC, REPEATABLE_READ)) { Long idx = (Long) cache.invoke(queueKey, new RemoveProcessor(id, rmvIdx)).get(); if (idx != null) { checkRemoved(idx); boolean rmv = cache.remove(itemKey(idx)); assert rmv : idx; } tx.commit(); break; } catch (ClusterTopologyCheckedException e) { if (e instanceof ClusterGroupEmptyCheckedException) throw e; if (cnt++ == MAX_UPDATE_RETRIES) throw e; else { U.warn(log, "Failed to add item, will retry [err=" + e + ']'); U.sleep(RETRY_DELAY); } } } } catch (IgniteCheckedException e) { throw U.convertException(e); } }
/** {@inheritDoc} */ @Override protected void afterTest() throws Exception { Transaction tx = jcache().unwrap(Ignite.class).transactions().tx(); if (tx != null) { tx.close(); fail("Cache transaction remained after test completion: " + tx); } for (int i = 0; i < gridCount(); i++) { info("Checking grid: " + i); while (true) { try { final int fi = i; assertTrue( "Cache is not empty: " + " localSize = " + jcache(fi).localSize(CachePeekMode.ALL) + ", local entries " + entrySet(jcache(fi).localEntries()), GridTestUtils.waitForCondition( // Preloading may happen as nodes leave, so we need to wait. new GridAbsPredicateX() { @Override public boolean applyx() throws IgniteCheckedException { jcache(fi).removeAll(); if (jcache(fi).size(CachePeekMode.ALL) > 0) { for (Cache.Entry<String, ?> k : jcache(fi).localEntries()) jcache(fi).remove(k.getKey()); } return jcache(fi).localSize(CachePeekMode.ALL) == 0; } }, getTestTimeout())); int primaryKeySize = jcache(i).localSize(CachePeekMode.PRIMARY); int keySize = jcache(i).localSize(); int size = jcache(i).localSize(); int globalSize = jcache(i).size(); int globalPrimarySize = jcache(i).size(CachePeekMode.PRIMARY); info( "Size after [idx=" + i + ", size=" + size + ", keySize=" + keySize + ", primarySize=" + primaryKeySize + ", globalSize=" + globalSize + ", globalPrimarySize=" + globalPrimarySize + ", entrySet=" + jcache(i).localEntries() + ']'); assertEquals( "Cache is not empty [idx=" + i + ", entrySet=" + jcache(i).localEntries() + ']', 0, jcache(i).localSize(CachePeekMode.ALL)); break; } catch (Exception e) { if (X.hasCause(e, ClusterTopologyCheckedException.class)) { info("Got topology exception while tear down (will retry in 1000ms)."); U.sleep(1000); } else throw e; } } for (Cache.Entry<String, Integer> entry : jcache(i).localEntries(CachePeekMode.SWAP)) jcache(i).remove(entry.getKey()); } assert jcache().unwrap(Ignite.class).transactions().tx() == null; assertEquals("Cache is not empty", 0, jcache().localSize(CachePeekMode.ALL)); resetStore(); }
/** * Check how prefetch override works. * * @throws Exception IF failed. */ public void testOpenPrefetchOverride() throws Exception { create(igfsSecondary, paths(DIR, SUBDIR), paths(FILE)); // Write enough data to the secondary file system. final int blockSize = IGFS_BLOCK_SIZE; IgfsOutputStream out = igfsSecondary.append(FILE, false); int totalWritten = 0; while (totalWritten < blockSize * 2 + chunk.length) { out.write(chunk); totalWritten += chunk.length; } out.close(); awaitFileClose(igfsSecondary.asSecondary(), FILE); // Instantiate file system with overridden "seq reads before prefetch" property. Configuration cfg = new Configuration(); cfg.addResource(U.resolveIgniteUrl(PRIMARY_CFG)); int seqReads = SEQ_READS_BEFORE_PREFETCH + 1; cfg.setInt(String.format(PARAM_IGFS_SEQ_READS_BEFORE_PREFETCH, "igfs:grid@"), seqReads); FileSystem fs = FileSystem.get(new URI(PRIMARY_URI), cfg); // Read the first two blocks. Path fsHome = new Path(PRIMARY_URI); Path dir = new Path(fsHome, DIR.name()); Path subdir = new Path(dir, SUBDIR.name()); Path file = new Path(subdir, FILE.name()); FSDataInputStream fsIn = fs.open(file); final byte[] readBuf = new byte[blockSize * 2]; fsIn.readFully(0, readBuf, 0, readBuf.length); // Wait for a while for prefetch to finish (if any). IgfsMetaManager meta = igfs.context().meta(); IgfsFileInfo info = meta.info(meta.fileId(FILE)); IgfsBlockKey key = new IgfsBlockKey(info.id(), info.affinityKey(), info.evictExclude(), 2); IgniteCache<IgfsBlockKey, byte[]> dataCache = igfs.context().kernalContext().cache().jcache(igfs.configuration().getDataCacheName()); for (int i = 0; i < 10; i++) { if (dataCache.containsKey(key)) break; else U.sleep(100); } fsIn.close(); // Remove the file from the secondary file system. igfsSecondary.delete(FILE, false); // Try reading the third block. Should fail. GridTestUtils.assertThrows( log, new Callable<Object>() { @Override public Object call() throws Exception { IgfsInputStream in0 = igfs.open(FILE); in0.seek(blockSize * 2); try { in0.read(readBuf); } finally { U.closeQuiet(in0); } return null; } }, IOException.class, "Failed to read data due to secondary file system exception: /dir/subdir/file"); }
/** * Sends cache query response. * * @param nodeId Node to send response. * @param res Cache query response. * @param timeout Message timeout. * @return {@code true} if response was sent, {@code false} otherwise. */ private boolean sendQueryResponse(UUID nodeId, GridCacheQueryResponse res, long timeout) { ClusterNode node = cctx.node(nodeId); if (node == null) return false; int attempt = 1; IgniteCheckedException err = null; while (!Thread.currentThread().isInterrupted()) { try { if (log.isDebugEnabled()) log.debug("Send query response: " + res); Object topic = topic(nodeId, res.requestId()); cctx.io() .sendOrderedMessage( node, topic, res, cctx.ioPolicy(), timeout > 0 ? timeout : Long.MAX_VALUE); return true; } catch (ClusterTopologyCheckedException ignored) { if (log.isDebugEnabled()) log.debug( "Failed to send query response since node left grid [nodeId=" + nodeId + ", res=" + res + "]"); return false; } catch (IgniteCheckedException e) { if (err == null) err = e; if (Thread.currentThread().isInterrupted()) break; if (attempt < RESEND_ATTEMPTS) { if (log.isDebugEnabled()) log.debug( "Failed to send queries response (will try again) [nodeId=" + nodeId + ", res=" + res + ", attempt=" + attempt + ", err=" + e + "]"); if (!Thread.currentThread().isInterrupted()) try { U.sleep(RESEND_FREQ); } catch (IgniteInterruptedCheckedException e1) { U.error( log, "Waiting for queries response resending was interrupted (response will not be sent) " + "[nodeId=" + nodeId + ", response=" + res + "]", e1); return false; } } else { U.error( log, "Failed to sender cache response [nodeId=" + nodeId + ", response=" + res + "]", err); return false; } } attempt++; } return false; }