use of org.apache.tephra.TransactionFailureException in project cdap by caskdata.
the class QueueTest method verifyQueueIsEmpty.
protected void verifyQueueIsEmpty(QueueName queueName, List<ConsumerConfig> consumerConfigs) throws Exception {
// Verify the queue is empty
Set<ConsumerGroupConfig> groupConfigs = Sets.newHashSet();
for (ConsumerConfig consumerConfig : consumerConfigs) {
try (QueueConsumer consumer = queueClientFactory.createConsumer(queueName, consumerConfig, -1)) {
groupConfigs.add(new ConsumerGroupConfig(consumerConfig));
TransactionContext txContext = createTxContext(consumer);
try {
txContext.start();
Assert.assertTrue(consumer.dequeue().isEmpty());
txContext.finish();
} catch (TransactionFailureException e) {
txContext.abort();
throw Throwables.propagate(e);
}
}
}
forceEviction(queueName, groupConfigs.size());
long newGroupId = groupConfigs.size();
groupConfigs.add(new ConsumerGroupConfig(newGroupId, 1, DequeueStrategy.FIFO, null));
configureGroups(queueName, groupConfigs);
// the queue has been consumed by n consumers. Use a consumerId greater than n to make sure it can dequeue.
ConsumerConfig consumerConfig = new ConsumerConfig(newGroupId, 0, 1, DequeueStrategy.FIFO, null);
resetConsumerState(queueName, consumerConfig);
try (QueueConsumer consumer = queueClientFactory.createConsumer(queueName, consumerConfig, -1)) {
TransactionContext txContext = createTxContext(consumer);
txContext.start();
DequeueResult<byte[]> result = consumer.dequeue();
if (!result.isEmpty()) {
StringBuilder resultString = new StringBuilder();
for (byte[] aResult : result) {
if (resultString.length() > 0) {
resultString.append(", ");
}
resultString.append(Bytes.toInt(aResult));
}
LOG.info("Queue should be empty but returned result: {}, value = ", result, resultString);
}
Assert.assertTrue("Entire queue should be evicted after test but dequeue succeeds.", result.isEmpty());
txContext.abort();
}
}
use of org.apache.tephra.TransactionFailureException in project cdap by caskdata.
the class QueueTest method createEnqueueRunnable.
protected Runnable createEnqueueRunnable(final QueueName queueName, final int count, final int batchSize, final CyclicBarrier barrier) {
return new Runnable() {
@Override
public void run() {
try {
if (barrier != null) {
barrier.await();
}
try (QueueProducer producer = queueClientFactory.createProducer(queueName)) {
TransactionContext txContext = createTxContext(producer);
LOG.info("Start enqueue {} entries.", count);
Stopwatch stopwatch = new Stopwatch();
stopwatch.start();
// Pre-Enqueue
int batches = count / batchSize;
List<QueueEntry> queueEntries = Lists.newArrayListWithCapacity(batchSize);
// include some negative hash values and some positive ones
int hashValueMultiplier = -1;
for (int i = 0; i < batches; i++) {
txContext.start();
try {
queueEntries.clear();
for (int j = 0; j < batchSize; j++) {
int val = i * batchSize + j;
byte[] queueData = Bytes.toBytes(val);
queueEntries.add(new QueueEntry("key", hashValueMultiplier * val, queueData));
hashValueMultiplier *= -1;
}
producer.enqueue(queueEntries);
txContext.finish();
} catch (TransactionFailureException e) {
LOG.error("Operation error", e);
txContext.abort();
throw Throwables.propagate(e);
}
}
long elapsed = stopwatch.elapsedTime(TimeUnit.MILLISECONDS);
LOG.info("Enqueue {} entries in {} ms for {}", count, elapsed, queueName.getSimpleName());
LOG.info("Enqueue avg {} entries per seconds for {}", (double) count * 1000 / elapsed, queueName.getSimpleName());
stopwatch.stop();
}
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
}
};
}
use of org.apache.tephra.TransactionFailureException in project cdap by caskdata.
the class TransactionContextTest method testPostCommitFailure.
@Test
public void testPostCommitFailure() throws TransactionFailureException, InterruptedException {
ds1.failPostCommitTxOnce = InduceFailure.ThrowException;
TransactionContext context = newTransactionContext(ds1, ds2);
// start transaction
context.start();
// add a change to ds1 and ds2
ds1.addChange(A);
ds2.addChange(B);
// commit transaction should fail but without rollback as the failure happens post-commit
try {
context.finish();
Assert.fail("post commit failed - exception should be thrown");
} catch (TransactionFailureException e) {
Assert.assertEquals("post failure", e.getCause().getMessage());
}
// verify both are committed and post-committed
Assert.assertTrue(ds1.started);
Assert.assertTrue(ds2.started);
Assert.assertTrue(ds1.checked);
Assert.assertTrue(ds2.checked);
Assert.assertTrue(ds1.committed);
Assert.assertTrue(ds2.committed);
Assert.assertTrue(ds1.postCommitted);
Assert.assertTrue(ds2.postCommitted);
Assert.assertFalse(ds1.rolledBack);
Assert.assertFalse(ds2.rolledBack);
Assert.assertEquals(txClient.state, DummyTxClient.CommitState.Committed);
}
use of org.apache.tephra.TransactionFailureException in project cdap by caskdata.
the class TransactionContextTest method testAndThenRemoveOnFailure.
@Test
public void testAndThenRemoveOnFailure() throws TransactionFailureException {
ds1.failCommitTxOnce = InduceFailure.ThrowException;
TransactionContext context = newTransactionContext();
context.start();
Assert.assertTrue(context.addTransactionAware(ds1));
ds1.addChange(A);
try {
context.finish();
Assert.fail("Persist should have failed - exception should be thrown");
} catch (TransactionFailureException e) {
Assert.assertEquals("persist failure", e.getCause().getMessage());
}
Assert.assertTrue(context.removeTransactionAware(ds1));
// Verify ds1 is rolled back
Assert.assertTrue(ds1.started);
Assert.assertTrue(ds1.checked);
Assert.assertTrue(ds1.committed);
Assert.assertFalse(ds1.postCommitted);
Assert.assertTrue(ds1.rolledBack);
Assert.assertEquals(txClient.state, DummyTxClient.CommitState.Aborted);
}
use of org.apache.tephra.TransactionFailureException in project cdap by caskdata.
the class TransactionContextTest method testGetTxAwareNameFails.
@Test
public void testGetTxAwareNameFails() throws TransactionFailureException {
// tests that under any scneario that can make a transaction fail, exceptions from
// getTransactionAwareName() do not affect proper abort, and the transaction context's
// state is clear (no current transaction) afterwards.
TransactionContext context = newTransactionContext(ds1);
ds1.failGetName = InduceFailure.ThrowException;
// the txAware will throw exceptions whenever getTransactionAwareName() is called.
// This is called in various failure scenarios. Test these scenarios one by one and check that
// the tx context is still functional after that.
// test failure during startTx()
ds1.failStartTxOnce = InduceFailure.ThrowException;
try {
context.start();
Assert.fail("Start should have failed - exception should be thrown");
} catch (TransactionFailureException e) {
Assert.assertEquals("start failure", e.getCause().getMessage());
Assert.assertNull(context.getCurrentTransaction());
}
// test failure during getTxChanges()
ds1.failChangesTxOnce = InduceFailure.ThrowException;
context.start();
try {
context.finish();
Assert.fail("Get changes should have failed - exception should be thrown");
} catch (TransactionFailureException e) {
Assert.assertEquals("changes failure", e.getCause().getMessage());
}
Assert.assertNull(context.getCurrentTransaction());
// test failure during commitTx()
ds1.failCommitTxOnce = InduceFailure.ThrowException;
context.start();
try {
context.finish();
Assert.fail("Persist should have failed - exception should be thrown");
} catch (TransactionFailureException e) {
Assert.assertEquals("persist failure", e.getCause().getMessage());
}
Assert.assertNull(context.getCurrentTransaction());
// test failure during rollbackTx()
ds1.failRollbackTxOnce = InduceFailure.ThrowException;
context.start();
try {
context.abort();
Assert.fail("Rollback should have failed - exception should be thrown");
} catch (TransactionFailureException e) {
Assert.assertEquals("rollback failure", e.getCause().getMessage());
}
Assert.assertNull(context.getCurrentTransaction());
// test failure during postTxCommit()
ds1.failPostCommitTxOnce = InduceFailure.ThrowException;
context.start();
try {
context.finish();
Assert.fail("Post Commit should have failed - exception should be thrown");
} catch (TransactionFailureException e) {
Assert.assertEquals("post failure", e.getCause().getMessage());
}
Assert.assertNull(context.getCurrentTransaction());
Assert.assertTrue(context.removeTransactionAware(ds1));
context.start();
context.finish();
Assert.assertNull(context.getCurrentTransaction());
}
Aggregations