use of com.palantir.common.base.AbortingVisitor in project atlasdb by palantir.
the class TransactionRangeMigrator method internalCopyRange.
private byte[] internalCopyRange(BatchingVisitable<RowResult<byte[]>> bv, final long maxBytes, final Transaction txn) {
final Mutable<byte[]> lastRowName = Mutables.newMutable(null);
final MutableLong bytesPut = new MutableLong(0L);
bv.batchAccept(readBatchSize, AbortingVisitors.batching(// even though no exception can be thrown :-(
new AbortingVisitor<RowResult<byte[]>, RuntimeException>() {
@Override
public boolean visit(RowResult<byte[]> rr) throws RuntimeException {
return TransactionRangeMigrator.this.internalCopyRow(rr, maxBytes, txn, bytesPut, lastRowName);
}
}));
return lastRowName.get();
}
use of com.palantir.common.base.AbortingVisitor in project atlasdb by palantir.
the class SnapshotTransactionTest method testTransactionAtomicity.
@Test
public void testTransactionAtomicity() throws Exception {
// This test runs multiple transactions in parallel, with KeyValueService.put calls throwing
// a RuntimeException from time to time and hanging other times. which effectively kills the
// thread. We ensure that every transaction either adds 5 rows to the table or adds 0 rows
// by checking at the end that the number of rows is a multiple of 5.
final TableReference tableRef = TABLE;
Random random = new Random(1);
final UnstableKeyValueService unstableKvs = new UnstableKeyValueService(keyValueService, random);
final TestTransactionManager unstableTransactionManager = new TestTransactionManagerImpl(unstableKvs, timestampService, lockClient, lockService, transactionService, conflictDetectionManager, sweepStrategyManager, sweepQueue);
ScheduledExecutorService service = PTExecutors.newScheduledThreadPool(20);
for (int i = 0; i < 30; i++) {
final int threadNumber = i;
service.schedule((Callable<Void>) () -> {
if (threadNumber == 10) {
unstableKvs.setRandomlyThrow(true);
}
if (threadNumber == 20) {
unstableKvs.setRandomlyHang(true);
}
Transaction transaction = unstableTransactionManager.createNewTransaction();
BatchingVisitable<RowResult<byte[]>> results = transaction.getRange(tableRef, RangeRequest.builder().build());
final MutableInt nextIndex = new MutableInt(0);
results.batchAccept(1, AbortingVisitors.batching((AbortingVisitor<RowResult<byte[]>, Exception>) row -> {
byte[] dataBytes = row.getColumns().get(PtBytes.toBytes("data"));
BigInteger dataValue = new BigInteger(dataBytes);
nextIndex.setValue(Math.max(nextIndex.toInteger(), dataValue.intValue() + 1));
return true;
}));
// rows to the table.
for (int j = 0; j < 5; j++) {
int rowNumber = nextIndex.toInteger() + j;
Cell cell = Cell.create(PtBytes.toBytes("row" + rowNumber), PtBytes.toBytes("data"));
transaction.put(tableRef, ImmutableMap.of(cell, BigInteger.valueOf(rowNumber).toByteArray()));
Thread.yield();
}
transaction.commit();
return null;
}, i * 20, TimeUnit.MILLISECONDS);
}
service.shutdown();
service.awaitTermination(1, TimeUnit.SECONDS);
// Verify each table has a number of rows that's a multiple of 5
Transaction verifyTransaction = txManager.createNewTransaction();
BatchingVisitable<RowResult<byte[]>> results = verifyTransaction.getRange(tableRef, RangeRequest.builder().build());
final MutableInt numRows = new MutableInt(0);
results.batchAccept(1, AbortingVisitors.batching((AbortingVisitor<RowResult<byte[]>, Exception>) row -> {
numRows.increment();
return true;
}));
Assert.assertEquals(0, numRows.toInteger() % 5);
}
use of com.palantir.common.base.AbortingVisitor in project atlasdb by palantir.
the class TableMigratorTest method testMigrationToDifferentKvs.
// Table/IndexDefinition syntax
@SuppressWarnings({ "checkstyle:Indentation", "checkstyle:RightCurly" })
@Test
public void testMigrationToDifferentKvs() throws TableMappingNotFoundException {
final TableReference tableRef = TableReference.create(Namespace.DEFAULT_NAMESPACE, "table");
final TableReference namespacedTableRef = TableReference.createFromFullyQualifiedName("namespace." + tableRef.getTablename());
TableDefinition definition = new TableDefinition() {
{
rowName();
rowComponent("r", ValueType.BLOB);
columns();
column("c", "c", ValueType.BLOB);
}
};
keyValueService.createTable(tableRef, definition.toTableMetadata().persistToBytes());
keyValueService.createTable(namespacedTableRef, definition.toTableMetadata().persistToBytes());
keyValueService.putMetadataForTable(namespacedTableRef, definition.toTableMetadata().persistToBytes());
final Cell theCell = Cell.create(PtBytes.toBytes("r1"), PtBytes.toBytes("c"));
final byte[] theValue = PtBytes.toBytes("v1");
txManager.runTaskWithRetry((TransactionTask<Void, RuntimeException>) txn -> {
Map<Cell, byte[]> values = ImmutableMap.of(theCell, theValue);
txn.put(tableRef, values);
txn.put(namespacedTableRef, values);
return null;
});
final InMemoryKeyValueService kvs2 = new InMemoryKeyValueService(false);
final ConflictDetectionManager cdm2 = ConflictDetectionManagers.createWithNoConflictDetection();
final SweepStrategyManager ssm2 = SweepStrategyManagers.completelyConservative(kvs2);
final TestTransactionManagerImpl txManager2 = new TestTransactionManagerImpl(kvs2, timestampService, lockClient, lockService, transactionService, cdm2, ssm2, MultiTableSweepQueueWriter.NO_OP);
kvs2.createTable(tableRef, definition.toTableMetadata().persistToBytes());
kvs2.createTable(namespacedTableRef, definition.toTableMetadata().persistToBytes());
TableReference checkpointTable = TableReference.create(Namespace.DEFAULT_NAMESPACE, "checkpoint");
GeneralTaskCheckpointer checkpointer = new GeneralTaskCheckpointer(checkpointTable, kvs2, txManager2);
for (final TableReference name : Lists.newArrayList(tableRef, namespacedTableRef)) {
TransactionRangeMigrator rangeMigrator = new TransactionRangeMigratorBuilder().srcTable(name).readTxManager(txManager).txManager(txManager2).checkpointer(checkpointer).build();
TableMigratorBuilder builder = new TableMigratorBuilder().srcTable(name).partitions(1).executor(PTExecutors.newSingleThreadExecutor()).checkpointer(checkpointer).rangeMigrator(rangeMigrator);
TableMigrator migrator = builder.build();
migrator.migrate();
}
checkpointer.deleteCheckpoints();
final ConflictDetectionManager verifyCdm = ConflictDetectionManagers.createWithNoConflictDetection();
final SweepStrategyManager verifySsm = SweepStrategyManagers.completelyConservative(kvs2);
final TestTransactionManagerImpl verifyTxManager = new TestTransactionManagerImpl(kvs2, timestampService, lockClient, lockService, transactionService, verifyCdm, verifySsm, MultiTableSweepQueueWriter.NO_OP);
final MutableLong count = new MutableLong();
for (final TableReference name : Lists.newArrayList(tableRef, namespacedTableRef)) {
verifyTxManager.runTaskReadOnly((TransactionTask<Void, RuntimeException>) txn -> {
BatchingVisitable<RowResult<byte[]>> bv = txn.getRange(name, RangeRequest.all());
bv.batchAccept(1000, AbortingVisitors.batching(new AbortingVisitor<RowResult<byte[]>, RuntimeException>() {
@Override
public boolean visit(RowResult<byte[]> item) throws RuntimeException {
Iterable<Entry<Cell, byte[]>> cells = item.getCells();
Entry<Cell, byte[]> entry = Iterables.getOnlyElement(cells);
Assert.assertEquals(theCell, entry.getKey());
Assert.assertArrayEquals(theValue, entry.getValue());
count.increment();
return true;
}
}));
return null;
});
}
Assert.assertEquals(2L, count.longValue());
}
use of com.palantir.common.base.AbortingVisitor in project atlasdb by palantir.
the class KvsRangeMigrator method internalCopyRange.
private byte[] internalCopyRange(BatchingVisitable<RowResult<byte[]>> bv, final long maxBytes, @Output final Map<Cell, byte[]> writeMap) {
final Mutable<byte[]> lastRowName = Mutables.newMutable(null);
final MutableLong bytesPut = new MutableLong(0L);
bv.batchAccept(readBatchSize, AbortingVisitors.batching(// even though no exception can be thrown :-(
new AbortingVisitor<RowResult<byte[]>, RuntimeException>() {
@Override
public boolean visit(RowResult<byte[]> rr) throws RuntimeException {
return KvsRangeMigrator.this.internalCopyRow(rr, maxBytes, writeMap, bytesPut, lastRowName);
}
}));
return lastRowName.get();
}
Aggregations