Search in sources :

Example 1 with PageLockListener

use of org.apache.ignite.internal.processors.cache.persistence.tree.util.PageLockListener in project ignite by apache.

the class JmhPageLockTrackerBenchmark method lockUnlock.

/**
 *  Mesure cost for (beforelock -> lock -> unlock) operation.
 */
@Benchmark
@BenchmarkMode(Mode.Throughput)
@Fork(1)
@Warmup(iterations = 10)
@Measurement(iterations = 10)
public // @OutputTimeUnit(TimeUnit.MICROSECONDS)
void lockUnlock(ThreadLocalState localState) {
    PageLockListener pl = localState.pl;
    for (int i = 0; i < localState.stackSize; i++) {
        int pageId = i + 1;
        pl.onBeforeReadLock(localState.StructureId, pageId, pageId);
        pl.onReadLock(localState.StructureId, pageId, pageId, pageId);
    }
    for (int i = localState.stackSize; i > 0; i--) {
        int pageId = i;
        pl.onReadUnlock(localState.StructureId, pageId, pageId, pageId);
    }
}
Also used : PageLockListener(org.apache.ignite.internal.processors.cache.persistence.tree.util.PageLockListener) Measurement(org.openjdk.jmh.annotations.Measurement) Warmup(org.openjdk.jmh.annotations.Warmup) Fork(org.openjdk.jmh.annotations.Fork) BenchmarkMode(org.openjdk.jmh.annotations.BenchmarkMode) Benchmark(org.openjdk.jmh.annotations.Benchmark)

Example 2 with PageLockListener

use of org.apache.ignite.internal.processors.cache.persistence.tree.util.PageLockListener in project ignite by apache.

the class SharedPageLockTrackerTest method testCloseListener.

/**
 * Tests that a structure gets unregistered when a listener gets closed.
 */
@Test
public void testCloseListener() {
    SharedPageLockTracker tracker = new SharedPageLockTracker();
    PageLockListener foo = tracker.registerStructure("foo");
    PageLockListener bar = tracker.registerStructure("bar");
    assertThat(tracker.dump().structureIdToStructureName.values(), containsInAnyOrder("foo", "bar"));
    IgniteUtils.closeQuiet(foo);
    assertThat(tracker.dump().structureIdToStructureName.values(), containsInAnyOrder("bar"));
    IgniteUtils.closeQuiet(bar);
    assertThat(tracker.dump().structureIdToStructureName.values(), is(empty()));
}
Also used : PageLockListener(org.apache.ignite.internal.processors.cache.persistence.tree.util.PageLockListener) Test(org.junit.Test)

Example 3 with PageLockListener

use of org.apache.ignite.internal.processors.cache.persistence.tree.util.PageLockListener in project ignite by apache.

the class SharedPageLockTrackerTest method doTestTakeDumpByCount.

/**
 */
private void doTestTakeDumpByCount(int pagesCnt, int structuresCnt, int dumpCnt, int threads) throws IgniteCheckedException, InterruptedException {
    SharedPageLockTracker sharedPageLockTracker = new SharedPageLockTracker();
    List<PageMeta> pageMetas = new CopyOnWriteArrayList<>();
    int id = 1;
    for (int i = 0; i < pagesCnt; i++) pageMetas.add(new PageMeta((id++) % structuresCnt, id++, id++, id++));
    List<PageLockListener> pageLsnrs = new ArrayList<>();
    for (int i = 0; i < structuresCnt; i++) pageLsnrs.add(sharedPageLockTracker.registerStructure("my-structure-" + i));
    AtomicBoolean stop = new AtomicBoolean();
    CountDownLatch awaitThreadStartLatch = new CountDownLatch(threads);
    IgniteInternalFuture f = GridTestUtils.runMultiThreadedAsync(() -> {
        List<PageLockListener> locks = new ArrayList<>(pageLsnrs);
        List<PageMeta> pages = new ArrayList<>();
        pages.addAll(pageMetas);
        boolean latchDown = false;
        while (!stop.get()) {
            Collections.shuffle(locks);
            Collections.shuffle(pages);
            for (PageLockListener lsnr : locks) {
                for (PageMeta pageMeta : pages) {
                    awaitRandom(50);
                    lsnr.onBeforeReadLock(pageMeta.structureId, pageMeta.pageId, pageMeta.page);
                    awaitRandom(50);
                    lsnr.onReadLock(pageMeta.structureId, pageMeta.pageId, pageMeta.page, pageMeta.pageAddr);
                }
            }
            awaitRandom(10);
            Collections.reverse(locks);
            Collections.reverse(pages);
            for (PageLockListener lsnr : locks) {
                for (PageMeta pageMeta : pages) {
                    awaitRandom(50);
                    lsnr.onReadUnlock(pageMeta.structureId, pageMeta.pageId, pageMeta.page, pageMeta.pageAddr);
                }
            }
            if (!latchDown) {
                awaitThreadStartLatch.countDown();
                latchDown = true;
            }
        }
    }, threads, "PageLocker");
    awaitThreadStartLatch.await();
    for (int i = 0; i < dumpCnt; i++) {
        awaitRandom(1000);
        SharedPageLockTrackerDump dump = sharedPageLockTracker.dump();
        assertEquals(threads, dump.threadPageLockStates.size());
        assertEquals(0, dump.threadPageLockStates.stream().filter(e -> e.invalidContext != null).count());
    }
    stop.set(true);
    f.get();
}
Also used : ArrayList(java.util.ArrayList) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) PageLockListener(org.apache.ignite.internal.processors.cache.persistence.tree.util.PageLockListener) CountDownLatch(java.util.concurrent.CountDownLatch) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList)

Example 4 with PageLockListener

use of org.apache.ignite.internal.processors.cache.persistence.tree.util.PageLockListener in project ignite by apache.

the class SharedPageLockTrackerTest method testMemoryLeakOnThreadTerminates.

/**
 * Test for checking that internal maps is not leaked after threads stopped.
 */
@Test
public void testMemoryLeakOnThreadTerminates() throws Exception {
    int threadLimits = 1000;
    int timeOutWorkerInterval = 10_000;
    Consumer<Set<PageLockThreadState>> handler = (threads) -> {
    };
    SharedPageLockTracker sharedPageLockTracker = new SharedPageLockTracker(threadLimits, timeOutWorkerInterval, handler, new MemoryCalculator());
    int threads = 10_000;
    int cacheId = 1;
    long pageId = 2;
    long page = 3;
    long pageAdder = 4;
    PageLockListener lt = sharedPageLockTracker.registerStructure("test");
    List<Thread> threadsList = new ArrayList<>(threads);
    String threadNamePreffix = "my-thread-";
    for (int i = 0; i < threads; i++) {
        Thread th = new Thread(() -> {
            lt.onBeforeReadLock(cacheId, pageId, page);
            lt.onReadLock(cacheId, pageId, page, pageAdder);
            lt.onReadUnlock(cacheId, pageId, page, pageAdder);
        });
        th.setName(threadNamePreffix + i);
        threadsList.add(th);
        th.start();
        System.out.println(">>> start thread:" + th.getName());
    }
    threadsList.forEach(th -> {
        try {
            System.out.println(">>> await thread:" + th.getName());
            th.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
    sharedPageLockTracker.start();
    SharedPageLockTrackerDump dump = sharedPageLockTracker.dump();
    assertTrue(dump.time > 0);
    assertTrue(!dump.threadPageLockStates.isEmpty());
    for (ThreadPageLockState threadPageLockState : dump.threadPageLockStates) {
        assertNull(threadPageLockState.invalidContext);
        assertTrue(threadPageLockState.threadName.startsWith(threadNamePreffix));
        assertSame(Thread.State.TERMINATED, threadPageLockState.state);
    }
    assertEquals(1, dump.structureIdToStructureName.size());
    synchronized (sharedPageLockTracker) {
        Map<Long, Thread> threadMap0 = U.field(sharedPageLockTracker, "threadIdToThreadRef");
        Map<Long, ?> threadStacksMap0 = U.field(sharedPageLockTracker, "threadStacks");
        // Stopped threads should remove from map after map limit reached.
        assertTrue(threadMap0.size() <= threadLimits);
        assertTrue(threadStacksMap0.size() <= threadLimits);
    }
    // Await cleanup worker interval.
    U.sleep(timeOutWorkerInterval + 1000);
    synchronized (sharedPageLockTracker) {
        Map<Long, Thread> threadMap1 = U.field(sharedPageLockTracker, "threadIdToThreadRef");
        Map<Long, ?> threadStacksMap1 = U.field(sharedPageLockTracker, "threadStacks");
        // Cleanup worker should remove all stopped threads.
        assertTrue(threadMap1.isEmpty());
        assertTrue(threadStacksMap1.isEmpty());
    }
    SharedPageLockTrackerDump dump1 = sharedPageLockTracker.dump();
    assertTrue(dump1.time > 0);
    assertTrue(dump1.threadPageLockStates.isEmpty());
}
Also used : IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) Arrays(java.util.Arrays) RunWith(org.junit.runner.RunWith) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) U(org.apache.ignite.internal.util.typedef.internal.U) HEAP_STACK(org.apache.ignite.internal.processors.cache.persistence.diagnostic.pagelocktracker.PageLockTrackerFactory.HEAP_STACK) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) PageLockListener(org.apache.ignite.internal.processors.cache.persistence.tree.util.PageLockListener) Assert.assertThat(org.junit.Assert.assertThat) Map(java.util.Map) IgniteUtils(org.apache.ignite.internal.util.IgniteUtils) OFF_HEAP_STACK(org.apache.ignite.internal.processors.cache.persistence.diagnostic.pagelocktracker.PageLockTrackerFactory.OFF_HEAP_STACK) OFF_HEAP_LOG(org.apache.ignite.internal.processors.cache.persistence.diagnostic.pagelocktracker.PageLockTrackerFactory.OFF_HEAP_LOG) Parameterized(org.junit.runners.Parameterized) Matchers.empty(org.hamcrest.Matchers.empty) Collection(java.util.Collection) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) Set(java.util.Set) Test(org.junit.Test) HEAP_LOG(org.apache.ignite.internal.processors.cache.persistence.diagnostic.pagelocktracker.PageLockTrackerFactory.HEAP_LOG) GridTestUtils(org.apache.ignite.testframework.GridTestUtils) Consumer(java.util.function.Consumer) SF(org.apache.ignite.testframework.GridTestUtils.SF) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) Matchers.containsInAnyOrder(org.hamcrest.Matchers.containsInAnyOrder) Matchers.is(org.hamcrest.Matchers.is) Collections(java.util.Collections) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) Set(java.util.Set) ArrayList(java.util.ArrayList) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) PageLockListener(org.apache.ignite.internal.processors.cache.persistence.tree.util.PageLockListener) Test(org.junit.Test)

Example 5 with PageLockListener

use of org.apache.ignite.internal.processors.cache.persistence.tree.util.PageLockListener in project ignite by apache.

the class SharedPageLockTrackerTest method testAutoDetectHangThreads.

/**
 */
@Test
public void testAutoDetectHangThreads() throws Exception {
    String thInWaitName = "threadInWait";
    String thInRunnableName = "threadInRunnable";
    String thInAwaitWithoutLocksName = "threadInAwaitWithoutLocks";
    AtomicReference<Exception> error = new AtomicReference<>();
    CountDownLatch awaitLatch = new CountDownLatch(1);
    SharedPageLockTracker sharedPageLockTracker = new SharedPageLockTracker(1000, 10_000, hangsThreads -> {
        if (hangsThreads.isEmpty()) {
            error.set(new Exception("No one thread is hangs."));
            return;
        }
        // Checking threads.
        for (PageLockThreadState state : hangsThreads) {
            String name = state.thread.getName();
            if (name.equals(thInAwaitWithoutLocksName)) {
                error.set(new Exception("Thread without locks should not be here." + state));
                continue;
            }
            if (name.equals(thInWaitName)) {
                if (state.heldLockCnt == 0)
                    error.set(new Exception("Thread should hold lock." + state));
                if (state.thread.getState() != Thread.State.WAITING)
                    error.set(new Exception("Thread should in WAITING state." + state));
                continue;
            }
            if (name.equals(thInRunnableName)) {
                if (state.heldLockCnt == 0)
                    error.set(new Exception("Thread should hold lock." + state));
                if (state.thread.getState() != Thread.State.RUNNABLE)
                    error.set(new Exception("Thread should in RUNNABLE state." + state));
                continue;
            }
        }
        awaitLatch.countDown();
    }, new MemoryCalculator());
    int cacheId = 1;
    long pageId = 2;
    long page = 3;
    long pageAdder = 4;
    PageLockListener lt = sharedPageLockTracker.registerStructure("test");
    Thread thInWait = new Thread(() -> {
        lt.onBeforeReadLock(cacheId, pageId, page);
        lt.onReadLock(cacheId, pageId, page, pageAdder);
        try {
            awaitLatch.await();
        } catch (InterruptedException ignored) {
        // No-op.
        }
    });
    thInWait.setName(thInWaitName);
    Thread thInRunnable = new Thread(() -> {
        lt.onBeforeReadLock(cacheId, pageId, page);
        lt.onReadLock(cacheId, pageId, page, pageAdder);
        while (awaitLatch.getCount() > 0) {
        // Busy wait. Can not park this thread, we should check running hangs too.
        }
    });
    thInRunnable.setName(thInRunnableName);
    Thread thInAwaitWithoutLocks = new Thread(() -> {
        lt.onBeforeReadLock(cacheId, pageId, page);
        lt.onReadLock(cacheId, pageId, page, pageAdder);
        lt.onReadUnlock(cacheId, pageId, page, pageAdder);
        try {
            awaitLatch.await();
        } catch (InterruptedException ignored) {
        // No-op.
        }
    });
    thInAwaitWithoutLocks.setName(thInAwaitWithoutLocksName);
    sharedPageLockTracker.start();
    thInWait.start();
    thInRunnable.start();
    thInAwaitWithoutLocks.start();
    thInWait.join();
    thInRunnable.join();
    thInAwaitWithoutLocks.join();
    if (error.get() != null)
        throw error.get();
}
Also used : AtomicReference(java.util.concurrent.atomic.AtomicReference) PageLockListener(org.apache.ignite.internal.processors.cache.persistence.tree.util.PageLockListener) CountDownLatch(java.util.concurrent.CountDownLatch) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) Test(org.junit.Test)

Aggregations

PageLockListener (org.apache.ignite.internal.processors.cache.persistence.tree.util.PageLockListener)11 Test (org.junit.Test)6 CountDownLatch (java.util.concurrent.CountDownLatch)5 ArrayList (java.util.ArrayList)4 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)3 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)3 IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)3 AtomicReference (java.util.concurrent.atomic.AtomicReference)2 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)2 SharedPageLockTracker (org.apache.ignite.internal.processors.cache.persistence.diagnostic.pagelocktracker.SharedPageLockTracker)2 SharedPageLockTrackerDump (org.apache.ignite.internal.processors.cache.persistence.diagnostic.pagelocktracker.SharedPageLockTrackerDump)2 ListeningTestLogger (org.apache.ignite.testframework.ListeningTestLogger)2 GridCommonAbstractTest (org.apache.ignite.testframework.junits.common.GridCommonAbstractTest)2 Path (java.nio.file.Path)1 Arrays (java.util.Arrays)1 Collection (java.util.Collection)1 Collections (java.util.Collections)1 List (java.util.List)1 Map (java.util.Map)1 Random (java.util.Random)1