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();
}
}
}
});
}
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();
}
});
}
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");
});
}
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);
}
});
}
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("Ургант");
});
}
Aggregations