Search in sources :

Example 1 with EntryLockedException

use of io.questdb.cairo.pool.ex.EntryLockedException in project questdb by bluestreak01.

the class ReaderPoolTest method testLockRaceAgainstGet.

@Test
public void testLockRaceAgainstGet() throws Exception {
    assertWithPool(pool -> {
        try (TableModel model = new TableModel(configuration, "x", PartitionBy.NONE).col("ts", ColumnType.DATE)) {
            CairoTestUtils.create(model);
        }
        for (int k = 0; k < 10; k++) {
            // allocate 32 readers to get to the start race at edge of next entry
            int n = 64;
            TableReader[] readers = new TableReader[n];
            try {
                for (int i = 0; i < n; i++) {
                    readers[i] = pool.get("x");
                    Assert.assertNotNull(readers[i]);
                }
                CyclicBarrier barrier = new CyclicBarrier(2);
                CountDownLatch latch = new CountDownLatch(1);
                new Thread(() -> {
                    try {
                        barrier.await();
                        boolean locked = pool.lock("x");
                        if (locked) {
                            pool.unlock("x");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        latch.countDown();
                    }
                }).start();
                barrier.await();
                try {
                    pool.get("x").close();
                } catch (EntryLockedException ignore) {
                }
                Assert.assertTrue(latch.await(2, TimeUnit.SECONDS));
            } finally {
                for (int i = 0; i < n; i++) {
                    readers[i].close();
                }
            }
        }
    });
}
Also used : SOCountDownLatch(io.questdb.mp.SOCountDownLatch) CountDownLatch(java.util.concurrent.CountDownLatch) EntryLockedException(io.questdb.cairo.pool.ex.EntryLockedException) BrokenBarrierException(java.util.concurrent.BrokenBarrierException) PoolClosedException(io.questdb.cairo.pool.ex.PoolClosedException) CyclicBarrier(java.util.concurrent.CyclicBarrier) EntryLockedException(io.questdb.cairo.pool.ex.EntryLockedException) Test(org.junit.Test)

Example 2 with EntryLockedException

use of io.questdb.cairo.pool.ex.EntryLockedException 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", "testing");
        try {
            Assert.assertNotNull(wy);
            Assert.assertTrue(wy.isOpen());
            // check that lock is successful
            Assert.assertNull(pool.lock("x", "testing"));
            // 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", "testing");
                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", "testing")) {
                    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", "testing")) {
                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) CountDownLatch(java.util.concurrent.CountDownLatch) EntryLockedException(io.questdb.cairo.pool.ex.EntryLockedException) Test(org.junit.Test)

Example 3 with EntryLockedException

use of io.questdb.cairo.pool.ex.EntryLockedException in project questdb by bluestreak01.

the class WriterPoolTest method testUnlockInAnotherThread.

@Test
public void testUnlockInAnotherThread() throws Exception {
    assertWithPool(pool -> {
        Assert.assertNull(pool.lock("x", "testing"));
        AtomicInteger errors = new AtomicInteger();
        CountDownLatch latch = new CountDownLatch(1);
        new Thread(() -> {
            try {
                try {
                    pool.unlock("x");
                    Assert.fail();
                } catch (CairoException e) {
                    TestUtils.assertContains(e.getFlyweightMessage(), "Not lock owner");
                }
            } catch (Throwable e) {
                e.printStackTrace();
                errors.incrementAndGet();
            } finally {
                latch.countDown();
            }
        }).start();
        Assert.assertTrue(latch.await(2, TimeUnit.SECONDS));
        Assert.assertEquals(0, errors.get());
        try {
            pool.get("x", "testing");
            Assert.fail();
        } catch (EntryLockedException ignore) {
        }
        pool.unlock("x");
    });
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CountDownLatch(java.util.concurrent.CountDownLatch) EntryLockedException(io.questdb.cairo.pool.ex.EntryLockedException) Test(org.junit.Test)

Example 4 with EntryLockedException

use of io.questdb.cairo.pool.ex.EntryLockedException in project questdb by bluestreak01.

the class LineTcpReceiverTest method test.

private void test(String authKeyId, PrivateKey authPrivateKey, int msgBufferSize, final int nRows, boolean expectDisconnect) throws Exception {
    this.authKeyId = authKeyId;
    this.msgBufferSize = msgBufferSize;
    assertMemoryLeak(() -> {
        final String[] locations = { "x london", "paris", "rome" };
        final CharSequenceHashSet tables = new CharSequenceHashSet();
        tables.add("weather1");
        tables.add("weather2");
        tables.add("weather3");
        SOCountDownLatch tablesCreated = new SOCountDownLatch();
        tablesCreated.setCount(tables.size());
        final Rnd rand = new Rnd();
        final StringBuilder[] expectedSbs = new StringBuilder[tables.size()];
        engine.setPoolListener((factoryType, thread, name, event, segment, position) -> {
            if (factoryType == PoolListener.SRC_WRITER && event == PoolListener.EV_RETURN) {
                if (tables.contains(name)) {
                    tablesCreated.countDown();
                }
            }
        });
        minIdleMsBeforeWriterRelease = 100;
        try (LineTcpReceiver ignored = LineTcpReceiver.create(lineConfiguration, sharedWorkerPool, LOG, engine)) {
            long startEpochMs = System.currentTimeMillis();
            sharedWorkerPool.assignCleaner(Path.CLEANER);
            sharedWorkerPool.start(LOG);
            try {
                final AbstractLineSender[] senders = new AbstractLineSender[tables.size()];
                for (int n = 0; n < senders.length; n++) {
                    if (null != authKeyId) {
                        AuthenticatedLineTcpSender sender = new AuthenticatedLineTcpSender(authKeyId, authPrivateKey, Net.parseIPv4("127.0.0.1"), bindPort, 4096);
                        sender.authenticate();
                        senders[n] = sender;
                    } else {
                        senders[n] = new LineTcpSender(Net.parseIPv4("127.0.0.1"), bindPort, 4096);
                    }
                    StringBuilder sb = new StringBuilder((nRows + 1) * lineConfiguration.getMaxMeasurementSize());
                    sb.append("location\ttemp\ttimestamp\n");
                    expectedSbs[n] = sb;
                }
                long ts = Os.currentTimeMicros();
                StringSink tsSink = new StringSink();
                for (int nRow = 0; nRow < nRows; nRow++) {
                    int nTable = nRow < tables.size() ? nRow : rand.nextInt(tables.size());
                    AbstractLineSender sender = senders[nTable];
                    StringBuilder sb = expectedSbs[nTable];
                    CharSequence tableName = tables.get(nTable);
                    sender.metric(tableName);
                    String location = locations[rand.nextInt(locations.length)];
                    sb.append(location);
                    sb.append('\t');
                    sender.tag("location", location);
                    int temp = rand.nextInt(100);
                    sb.append(temp);
                    sb.append('\t');
                    sender.field("temp", temp);
                    tsSink.clear();
                    TimestampFormatUtils.appendDateTimeUSec(tsSink, ts);
                    sb.append(tsSink);
                    sb.append('\n');
                    sender.$(ts * 1000);
                    sender.flush();
                    if (expectDisconnect) {
                        // To prevent all data being buffered before the expected disconnect slow sending
                        Os.sleep(100);
                    }
                    ts += rand.nextInt(1000);
                }
                for (int n = 0; n < senders.length; n++) {
                    AbstractLineSender sender = senders[n];
                    sender.close();
                }
                Assert.assertFalse(expectDisconnect);
                boolean ready = tablesCreated.await(TimeUnit.MINUTES.toNanos(1));
                if (!ready) {
                    throw new IllegalStateException("Timeout waiting for tables to be created");
                }
                int nRowsWritten;
                do {
                    nRowsWritten = 0;
                    long timeTakenMs = System.currentTimeMillis() - startEpochMs;
                    if (timeTakenMs > TEST_TIMEOUT_IN_MS) {
                        LOG.error().$("after ").$(timeTakenMs).$("ms tables only had ").$(nRowsWritten).$(" rows out of ").$(nRows).$();
                        break;
                    }
                    Thread.yield();
                    for (int n = 0; n < tables.size(); n++) {
                        CharSequence tableName = tables.get(n);
                        while (true) {
                            try (TableReader reader = engine.getReader(AllowAllCairoSecurityContext.INSTANCE, tableName)) {
                                TableReaderRecordCursor cursor = reader.getCursor();
                                while (cursor.hasNext()) {
                                    nRowsWritten++;
                                }
                                break;
                            } catch (EntryLockedException ex) {
                                LOG.info().$("retrying read for ").$(tableName).$();
                                LockSupport.parkNanos(1);
                            }
                        }
                    }
                } while (nRowsWritten < nRows);
                LOG.info().$(nRowsWritten).$(" rows written").$();
            } finally {
                sharedWorkerPool.halt();
            }
        } finally {
            engine.setPoolListener(null);
        }
        for (int n = 0; n < tables.size(); n++) {
            CharSequence tableName = tables.get(n);
            LOG.info().$("checking table ").$(tableName).$();
            assertTable(expectedSbs[n], tableName);
        }
    });
}
Also used : LineTcpSender(io.questdb.cutlass.line.LineTcpSender) AuthenticatedLineTcpSender(io.questdb.cutlass.line.AuthenticatedLineTcpSender) StringSink(io.questdb.std.str.StringSink) SOCountDownLatch(io.questdb.mp.SOCountDownLatch) AbstractLineSender(io.questdb.cutlass.line.AbstractLineSender) AuthenticatedLineTcpSender(io.questdb.cutlass.line.AuthenticatedLineTcpSender) EntryLockedException(io.questdb.cairo.pool.ex.EntryLockedException)

Example 5 with EntryLockedException

use of io.questdb.cairo.pool.ex.EntryLockedException in project questdb by bluestreak01.

the class ReaderPoolTest method testUnlockByAnotherThread.

@Test
public void testUnlockByAnotherThread() throws Exception {
    assertWithPool(pool -> {
        Assert.assertTrue(pool.lock("Ургант"));
        AtomicInteger errors = new AtomicInteger();
        CountDownLatch latch = new CountDownLatch(1);
        new Thread(() -> {
            try {
                try {
                    pool.unlock("Ургант");
                    Assert.fail();
                } catch (CairoException e) {
                    TestUtils.assertContains(e.getFlyweightMessage(), "Not the lock owner of Ургант");
                }
            } catch (Throwable e) {
                e.printStackTrace();
                errors.incrementAndGet();
            } finally {
                latch.countDown();
            }
        }).start();
        Assert.assertTrue(latch.await(2, TimeUnit.SECONDS));
        Assert.assertEquals(0, errors.get());
        try {
            pool.get("Ургант");
            Assert.fail();
        } catch (EntryLockedException ignore) {
        }
        pool.unlock("Ургант");
    });
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SOCountDownLatch(io.questdb.mp.SOCountDownLatch) CountDownLatch(java.util.concurrent.CountDownLatch) EntryLockedException(io.questdb.cairo.pool.ex.EntryLockedException) Test(org.junit.Test)

Aggregations

EntryLockedException (io.questdb.cairo.pool.ex.EntryLockedException)6 CountDownLatch (java.util.concurrent.CountDownLatch)4 Test (org.junit.Test)4 SOCountDownLatch (io.questdb.mp.SOCountDownLatch)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 PoolClosedException (io.questdb.cairo.pool.ex.PoolClosedException)1 AbstractLineSender (io.questdb.cutlass.line.AbstractLineSender)1 AuthenticatedLineTcpSender (io.questdb.cutlass.line.AuthenticatedLineTcpSender)1 LineTcpSender (io.questdb.cutlass.line.LineTcpSender)1 FlyweightCharSequence (io.questdb.std.str.FlyweightCharSequence)1 StringSink (io.questdb.std.str.StringSink)1 BrokenBarrierException (java.util.concurrent.BrokenBarrierException)1 CyclicBarrier (java.util.concurrent.CyclicBarrier)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1