/** {@inheritDoc} */ @Override protected void body() throws InterruptedException, IgniteInterruptedCheckedException { if (log.isDebugEnabled()) log.debug("GC worker started."); File workTokDir = tokDir.getParentFile(); assert workTokDir != null; boolean lastRunNeeded = true; while (true) { try { // Sleep only if not cancelled. if (lastRunNeeded) Thread.sleep(GC_FREQ); } catch (InterruptedException ignored) { // No-op. } if (log.isDebugEnabled()) log.debug("Starting GC iteration."); cleanupResources(workTokDir); // Process spaces created by this endpoint. if (log.isDebugEnabled()) log.debug("Processing local spaces."); for (IpcSharedMemoryClientEndpoint e : endpoints) { if (log.isDebugEnabled()) log.debug("Processing endpoint: " + e); if (!e.checkOtherPartyAlive()) { endpoints.remove(e); if (log.isDebugEnabled()) log.debug("Removed endpoint: " + e); } } if (isCancelled()) { if (lastRunNeeded) { lastRunNeeded = false; // Clear interrupted status. Thread.interrupted(); } else { Thread.currentThread().interrupt(); break; } } } }
/** * JUnit. * * @throws Exception If failed. */ @SuppressWarnings({"TooBroadScope"}) public void testRestarts() throws Exception { int duration = 60 * 1000; int qryThreadNum = 10; final long nodeLifeTime = 2 * 1000; final int logFreq = 20; final IgniteCache<Integer, Integer> cache = grid(0).cache(null); assert cache != null; for (int i = 0; i < KEY_CNT; i++) cache.put(i, i); assertEquals(KEY_CNT, cache.localSize()); final AtomicInteger qryCnt = new AtomicInteger(); final AtomicBoolean done = new AtomicBoolean(); IgniteInternalFuture<?> fut1 = multithreadedAsync( new CAX() { @Override public void applyx() throws IgniteCheckedException { while (!done.get()) { Collection<Cache.Entry<Integer, Integer>> res = cache.query(new SqlQuery(Integer.class, "_val >= 0")).getAll(); assertFalse(res.isEmpty()); int c = qryCnt.incrementAndGet(); if (c % logFreq == 0) info("Executed queries: " + c); } } }, qryThreadNum); final AtomicInteger restartCnt = new AtomicInteger(); CollectingEventListener lsnr = new CollectingEventListener(); for (int i = 0; i < GRID_CNT; i++) grid(i).events().localListen(lsnr, EventType.EVT_CACHE_REBALANCE_STOPPED); IgniteInternalFuture<?> fut2 = multithreadedAsync( new Callable<Object>() { @SuppressWarnings({"BusyWait"}) @Override public Object call() throws Exception { while (!done.get()) { int idx = GRID_CNT; startGrid(idx); Thread.sleep(nodeLifeTime); stopGrid(idx); int c = restartCnt.incrementAndGet(); if (c % logFreq == 0) info("Node restarts: " + c); } return true; } }, 1); Thread.sleep(duration); done.set(true); fut1.get(); fut2.get(); info("Awaiting rebalance events [restartCnt=" + restartCnt.get() + ']'); boolean success = lsnr.awaitEvents(GRID_CNT * 2 * restartCnt.get(), 15000); for (int i = 0; i < GRID_CNT; i++) grid(i).events().stopLocalListen(lsnr, EventType.EVT_CACHE_REBALANCE_STOPPED); assert success; }