Search in sources :

Example 6 with EntryUnavailableException

use of com.questdb.cairo.pool.ex.EntryUnavailableException in project questdb by bluestreak01.

the class WriterPoolTest method testTwoThreadsRaceToAllocateAndLock.

@Test
public void testTwoThreadsRaceToAllocateAndLock() throws Exception {
    assertWithPool(pool -> {
        for (int k = 0; k < 1000; k++) {
            int n = 2;
            final CyclicBarrier barrier = new CyclicBarrier(n);
            final CountDownLatch halt = new CountDownLatch(n);
            final AtomicInteger errors = new AtomicInteger();
            final AtomicInteger writerCount = new AtomicInteger();
            for (int i = 0; i < n; i++) {
                new Thread(() -> {
                    try {
                        barrier.await();
                        try (TableWriter w = pool.get("z")) {
                            writerCount.incrementAndGet();
                            populate(w);
                            Assert.assertTrue(w == pool.get("z"));
                        } catch (EntryUnavailableException ignored) {
                        }
                        // lock frees up writer, make sure on next iteration threads have something to compete for
                        if (pool.lock("z")) {
                            pool.unlock("z");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        errors.incrementAndGet();
                    } finally {
                        halt.countDown();
                    }
                }).start();
            }
            halt.await();
            // this check is unreliable on slow build servers
            // it is very often the case that there are limited number of cores
            // available and threads execute sequentially rather than
            // simultaneously. We should check that none of the threads
            // receive error.
            Assert.assertTrue(writerCount.get() > 0);
            Assert.assertEquals(0, errors.get());
            Assert.assertEquals(0, pool.countFreeWriters());
        }
    });
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) EntryUnavailableException(com.questdb.cairo.pool.ex.EntryUnavailableException) CountDownLatch(java.util.concurrent.CountDownLatch) EntryLockedException(com.questdb.cairo.pool.ex.EntryLockedException) EntryUnavailableException(com.questdb.cairo.pool.ex.EntryUnavailableException) PoolClosedException(com.questdb.cairo.pool.ex.PoolClosedException) CyclicBarrier(java.util.concurrent.CyclicBarrier) Test(org.junit.Test)

Example 7 with EntryUnavailableException

use of com.questdb.cairo.pool.ex.EntryUnavailableException in project questdb by bluestreak01.

the class WriterPoolTest method testLockUnlock.

@Test
public void testLockUnlock() throws Exception {
    try (TableModel model = new TableModel(configuration, "x", PartitionBy.NONE).col("ts", ColumnType.DATE)) {
        CairoTestUtils.create(model);
    }
    try (TableModel model = new TableModel(configuration, "y", PartitionBy.NONE).col("ts", ColumnType.DATE)) {
        CairoTestUtils.create(model);
    }
    assertWithPool(pool -> {
        TableWriter wy = pool.get("y");
        Assert.assertNotNull(wy);
        Assert.assertTrue(wy.isOpen());
        try {
            // check that lock is successful
            Assert.assertTrue(pool.lock("x"));
            // check that writer x is closed and writer y is open (lock must not spill out to other writers)
            Assert.assertTrue(wy.isOpen());
            // check that when name is locked writers are not created
            try {
                pool.get("x");
                Assert.fail();
            } catch (EntryLockedException ignored) {
            }
            final CountDownLatch done = new CountDownLatch(1);
            final AtomicBoolean result = new AtomicBoolean();
            // have new thread try to allocated this writer
            new Thread(() -> {
                try (TableWriter ignored = pool.get("x")) {
                    result.set(false);
                } catch (EntryUnavailableException ignored) {
                    result.set(true);
                } catch (CairoException e) {
                    e.printStackTrace();
                    result.set(false);
                }
                done.countDown();
            }).start();
            Assert.assertTrue(done.await(1, TimeUnit.SECONDS));
            Assert.assertTrue(result.get());
            pool.unlock("x");
            try (TableWriter wx = pool.get("x")) {
                Assert.assertNotNull(wx);
                Assert.assertTrue(wx.isOpen());
                try {
                    // unlocking writer that has not been locked must produce exception
                    // and not affect open writer
                    pool.unlock("x");
                    Assert.fail();
                } catch (CairoException ignored) {
                }
                Assert.assertTrue(wx.isOpen());
            }
        } finally {
            wy.close();
        }
    });
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) EntryUnavailableException(com.questdb.cairo.pool.ex.EntryUnavailableException) CountDownLatch(java.util.concurrent.CountDownLatch) EntryLockedException(com.questdb.cairo.pool.ex.EntryLockedException) Test(org.junit.Test)

Aggregations

EntryLockedException (com.questdb.cairo.pool.ex.EntryLockedException)7 EntryUnavailableException (com.questdb.cairo.pool.ex.EntryUnavailableException)7 CountDownLatch (java.util.concurrent.CountDownLatch)7 Test (org.junit.Test)7 PoolClosedException (com.questdb.cairo.pool.ex.PoolClosedException)6 CyclicBarrier (java.util.concurrent.CyclicBarrier)6 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)6 RecordCursor (com.questdb.common.RecordCursor)2 RecordSourcePrinter (com.questdb.ql.RecordSourcePrinter)2 StringSink (com.questdb.std.str.StringSink)2 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1