use of io.pravega.controller.store.stream.records.CompletedTxnRecord in project pravega by pravega.
the class ControllerMetadataJsonSerializerTest method testCompletedTxnRecord.
@Test
public void testCompletedTxnRecord() {
CompletedTxnRecord record = new CompletedTxnRecord(1L, TxnStatus.COMMITTED);
testRecordSerialization(record, CompletedTxnRecord.class);
}
use of io.pravega.controller.store.stream.records.CompletedTxnRecord in project pravega by pravega.
the class PersistentStreamBase method commitTransaction.
@VisibleForTesting
public CompletableFuture<TxnStatus> commitTransaction(final UUID txId, OperationContext context) {
Preconditions.checkNotNull(context, "Operation context cannot be null");
int epoch = RecordHelper.getTransactionEpoch(txId);
return checkTransactionStatus(txId, context).thenApply(x -> {
switch(x) {
// Only sealed transactions can be committed
case COMMITTED:
case COMMITTING:
return x;
case OPEN:
case ABORTING:
case ABORTED:
throw StoreException.create(StoreException.Type.ILLEGAL_STATE, String.format("Stream: %s Transaction: %s State: %s", getName(), txId.toString(), x.toString()));
case UNKNOWN:
default:
throw StoreException.create(StoreException.Type.DATA_NOT_FOUND, String.format("Stream: %s Transaction: %s", getName(), txId.toString()));
}
}).thenCompose(x -> {
if (x.equals(TxnStatus.COMMITTING)) {
return createCompletedTxEntry(txId, new CompletedTxnRecord(System.currentTimeMillis(), TxnStatus.COMMITTED), context);
} else {
// already committed, do nothing
return CompletableFuture.completedFuture(null);
}
}).thenCompose(x -> removeActiveTxEntry(epoch, txId, context)).thenApply(x -> TxnStatus.COMMITTED);
}
use of io.pravega.controller.store.stream.records.CompletedTxnRecord in project pravega by pravega.
the class PravegaTablesStream method createCompletedTxEntries.
private CompletableFuture<Void> createCompletedTxEntries(List<Map.Entry<String, CompletedTxnRecord>> complete, OperationContext context) {
Preconditions.checkNotNull(context, "operation context cannot be null");
Integer batch = currentBatchSupplier.get();
String tableName = getCompletedTransactionsBatchTableName(batch);
return Futures.toVoid(Futures.exceptionallyComposeExpecting(storeHelper.addNewEntriesIfAbsent(tableName, complete, CompletedTxnRecord::toBytes, context.getRequestId()), DATA_NOT_FOUND_PREDICATE, () -> tryCreateBatchTable(batch, context).thenCompose(v -> storeHelper.addNewEntriesIfAbsent(tableName, complete, CompletedTxnRecord::toBytes, context.getRequestId())))).exceptionally(e -> {
throw new CompletionException(e);
});
}
use of io.pravega.controller.store.stream.records.CompletedTxnRecord in project pravega by pravega.
the class PersistentStreamBase method abortTransaction.
@Override
public CompletableFuture<TxnStatus> abortTransaction(final UUID txId, OperationContext context) {
Preconditions.checkNotNull(context, "Operation context cannot be null");
int epoch = RecordHelper.getTransactionEpoch(txId);
return checkTransactionStatus(txId, context).thenApply(x -> {
switch(x) {
case ABORTING:
case ABORTED:
return x;
case OPEN:
case COMMITTING:
case COMMITTED:
throw StoreException.create(StoreException.Type.ILLEGAL_STATE, "Stream: " + getName() + " Transaction: " + txId.toString() + " State: " + x.name());
case UNKNOWN:
default:
throw StoreException.create(StoreException.Type.DATA_NOT_FOUND, "Stream: " + getName() + " Transaction: " + txId.toString());
}
}).thenCompose(x -> {
if (x.equals(TxnStatus.ABORTING)) {
return createCompletedTxEntry(txId, new CompletedTxnRecord(System.currentTimeMillis(), TxnStatus.ABORTED), context);
} else {
// already aborted, do nothing
return CompletableFuture.completedFuture(null);
}
}).thenCompose(y -> removeActiveTxEntry(epoch, txId, context)).thenApply(y -> TxnStatus.ABORTED);
}
use of io.pravega.controller.store.stream.records.CompletedTxnRecord in project pravega by pravega.
the class PravegaTablesStreamMetadataStoreTest method testGarbageCollection.
@Test
public void testGarbageCollection() {
try (PravegaTablesStreamMetadataStore testStore = new PravegaTablesStreamMetadataStore(segmentHelperMockForTables, PRAVEGA_ZK_CURATOR_RESOURCE.client, executor, Duration.ofSeconds(100), GrpcAuthHelper.getDisabledAuthHelper())) {
AtomicInteger currentBatch = new AtomicInteger(0);
Supplier<Integer> supplier = currentBatch::get;
ZKGarbageCollector gc = mock(ZKGarbageCollector.class);
doAnswer(x -> supplier.get()).when(gc).getLatestBatch();
testStore.setCompletedTxnGCRef(gc);
String scope = "scopeGC";
String stream = "streamGC";
testStore.createScope(scope, null, executor).join();
StreamConfiguration config = StreamConfiguration.builder().scalingPolicy(ScalingPolicy.fixed(1)).build();
testStore.createStream(scope, stream, config, System.currentTimeMillis(), null, executor).join();
// batch 0
UUID txnId0 = testStore.generateTransactionId(scope, stream, null, executor).join();
createAndCommitTransaction(scope, stream, txnId0, testStore);
UUID txnId1 = testStore.generateTransactionId(scope, stream, null, executor).join();
createAndCommitTransaction(scope, stream, txnId1, testStore);
// verify that the completed txn record is created in batch 0
Set<Integer> batches = getAllBatches(testStore);
assertEquals(batches.size(), 1);
assertTrue(batches.contains(0));
Map<String, CompletedTxnRecord> transactions = getAllTransactionsInBatch(testStore, 0);
// verify that transaction is present in batch 0
assertTrue(transactions.containsKey(PravegaTablesStream.getCompletedTransactionKey(scope, stream, txnId1.toString())));
// run gc. There should be no purge.
testStore.gcCompletedTxn().join();
batches = getAllBatches(testStore);
// verify no purge of batch
assertEquals(batches.size(), 1);
assertTrue(batches.contains(0));
TxnStatus status = testStore.transactionStatus(scope, stream, txnId1, null, executor).join();
assertEquals(status, TxnStatus.COMMITTED);
// create batch 1
currentBatch.incrementAndGet();
UUID txnId2 = testStore.generateTransactionId(scope, stream, null, executor).join();
createAndCommitTransaction(scope, stream, txnId2, testStore);
// verify that the completed txn record is created in batch 1
batches = getAllBatches(testStore);
assertEquals(batches.size(), 2);
transactions = getAllTransactionsInBatch(testStore, 1);
// verify that transaction is present in batch 1
assertTrue(transactions.containsKey(PravegaTablesStream.getCompletedTransactionKey(scope, stream, txnId2.toString())));
// run gc. There should be no purge.
testStore.gcCompletedTxn().join();
batches = getAllBatches(testStore);
// verify no purge of batch
assertEquals(batches.size(), 2);
assertTrue(batches.contains(0));
assertTrue(batches.contains(1));
status = testStore.transactionStatus(scope, stream, txnId1, null, executor).join();
assertEquals(status, TxnStatus.COMMITTED);
status = testStore.transactionStatus(scope, stream, txnId2, null, executor).join();
assertEquals(status, TxnStatus.COMMITTED);
// create batch 2
currentBatch.incrementAndGet();
UUID txnId3 = testStore.generateTransactionId(scope, stream, null, executor).join();
createAndCommitTransaction(scope, stream, txnId3, testStore);
// verify that the completed txn record is created in batch 2
batches = getAllBatches(testStore);
assertEquals(batches.size(), 3);
assertTrue(batches.contains(0));
assertTrue(batches.contains(1));
assertTrue(batches.contains(2));
status = testStore.transactionStatus(scope, stream, txnId1, null, executor).join();
assertEquals(status, TxnStatus.COMMITTED);
status = testStore.transactionStatus(scope, stream, txnId2, null, executor).join();
assertEquals(status, TxnStatus.COMMITTED);
status = testStore.transactionStatus(scope, stream, txnId3, null, executor).join();
assertEquals(status, TxnStatus.COMMITTED);
// dont run gc. let batches get accumulated.
transactions = getAllTransactionsInBatch(testStore, 2);
// verify that transaction is present in batch 2
assertTrue(transactions.containsKey(PravegaTablesStream.getCompletedTransactionKey(scope, stream, txnId3.toString())));
// create batch 3
currentBatch.incrementAndGet();
UUID txnId4 = testStore.generateTransactionId(scope, stream, null, executor).join();
createAndCommitTransaction(scope, stream, txnId4, testStore);
// verify that the completed txn record is created in batch 3
batches = getAllBatches(testStore);
assertEquals(batches.size(), 4);
assertTrue(batches.contains(0));
assertTrue(batches.contains(1));
assertTrue(batches.contains(2));
assertTrue(batches.contains(3));
status = testStore.transactionStatus(scope, stream, txnId1, null, executor).join();
assertEquals(status, TxnStatus.COMMITTED);
status = testStore.transactionStatus(scope, stream, txnId2, null, executor).join();
assertEquals(status, TxnStatus.COMMITTED);
status = testStore.transactionStatus(scope, stream, txnId3, null, executor).join();
assertEquals(status, TxnStatus.COMMITTED);
status = testStore.transactionStatus(scope, stream, txnId4, null, executor).join();
assertEquals(status, TxnStatus.COMMITTED);
transactions = getAllTransactionsInBatch(testStore, 3);
// verify that transaction is present in batch 3
assertTrue(transactions.containsKey(PravegaTablesStream.getCompletedTransactionKey(scope, stream, txnId4.toString())));
// check that we are able to get status for all 4 transactions.
status = testStore.transactionStatus(scope, stream, txnId1, null, executor).join();
assertEquals(status, TxnStatus.COMMITTED);
status = testStore.transactionStatus(scope, stream, txnId2, null, executor).join();
assertEquals(status, TxnStatus.COMMITTED);
status = testStore.transactionStatus(scope, stream, txnId3, null, executor).join();
assertEquals(status, TxnStatus.COMMITTED);
status = testStore.transactionStatus(scope, stream, txnId4, null, executor).join();
assertEquals(status, TxnStatus.COMMITTED);
// run gc. There should be two purges.
testStore.gcCompletedTxn().join();
batches = getAllBatches(testStore);
assertEquals(batches.size(), 2);
assertTrue(batches.contains(2));
assertTrue(batches.contains(3));
// we should be able to get txn status for txn3 and txn4 but should get unknown for txn1 and txn2
status = testStore.transactionStatus(scope, stream, txnId1, null, executor).join();
assertEquals(status, TxnStatus.UNKNOWN);
status = testStore.transactionStatus(scope, stream, txnId2, null, executor).join();
assertEquals(status, TxnStatus.UNKNOWN);
status = testStore.transactionStatus(scope, stream, txnId3, null, executor).join();
assertEquals(status, TxnStatus.COMMITTED);
status = testStore.transactionStatus(scope, stream, txnId4, null, executor).join();
assertEquals(status, TxnStatus.COMMITTED);
}
}
Aggregations