use of io.pravega.controller.store.stream.tables.ActiveTxnRecord in project pravega by pravega.
the class InMemoryStream method sealActiveTx.
@Override
CompletableFuture<Void> sealActiveTx(int epoch, UUID txId, boolean commit, ActiveTxnRecord txnRecord, int version) {
Preconditions.checkNotNull(txId);
CompletableFuture<Void> result = new CompletableFuture<>();
synchronized (txnsLock) {
if (!activeTxns.containsKey(txId.toString())) {
result.completeExceptionally(StoreException.create(StoreException.Type.DATA_NOT_FOUND, "Stream: " + getName() + " Transaction: " + txId.toString()));
} else {
activeTxns.compute(txId.toString(), (x, y) -> {
if (version != y.getVersion()) {
result.completeExceptionally(StoreException.create(StoreException.Type.WRITE_CONFLICT, "Stream: " + getName() + " Transaction: " + txId.toString()));
return y;
} else {
ActiveTxnRecord previous = ActiveTxnRecord.parse(y.getData());
ActiveTxnRecord updated = new ActiveTxnRecord(previous.getTxCreationTimestamp(), previous.getLeaseExpiryTime(), previous.getMaxExecutionExpiryTime(), previous.getScaleGracePeriod(), commit ? TxnStatus.COMMITTING : TxnStatus.ABORTING);
result.complete(null);
return new Data<>(updated.toByteArray(), y.getVersion() + 1);
}
});
}
}
return result;
}
use of io.pravega.controller.store.stream.tables.ActiveTxnRecord in project pravega by pravega.
the class PersistentStreamBase method pingTransaction.
@Override
public CompletableFuture<VersionedTransactionData> pingTransaction(final VersionedTransactionData txnData, final long lease) {
// Update txn record with new lease value and return versioned tx data.
final int epoch = txnData.getEpoch();
final UUID txnId = txnData.getId();
final int version = txnData.getVersion();
final long creationTime = txnData.getCreationTime();
final long maxExecutionExpiryTime = txnData.getMaxExecutionExpiryTime();
final long scaleGracePeriod = txnData.getScaleGracePeriod();
final TxnStatus status = txnData.getStatus();
final ActiveTxnRecord newData = new ActiveTxnRecord(creationTime, System.currentTimeMillis() + lease, maxExecutionExpiryTime, scaleGracePeriod, status);
final Data<Integer> data = new Data<>(newData.toByteArray(), version);
return updateActiveTx(epoch, txnId, data).thenApply(x -> new VersionedTransactionData(epoch, txnId, version + 1, status, creationTime, maxExecutionExpiryTime, scaleGracePeriod));
}
use of io.pravega.controller.store.stream.tables.ActiveTxnRecord in project pravega by pravega.
the class ZKStream method sealActiveTx.
@Override
CompletableFuture<Void> sealActiveTx(final int epoch, final UUID txId, final boolean commit, final ActiveTxnRecord previous, final int version) {
final String activePath = getActiveTxPath(epoch, txId.toString());
final ActiveTxnRecord updated = new ActiveTxnRecord(previous.getTxCreationTimestamp(), previous.getLeaseExpiryTime(), previous.getMaxExecutionExpiryTime(), previous.getScaleGracePeriod(), commit ? TxnStatus.COMMITTING : TxnStatus.ABORTING);
final Data<Integer> data = new Data<>(updated.toByteArray(), version);
return store.setData(activePath, data).thenApply(x -> cache.invalidateCache(activePath)).whenComplete((r, e) -> cache.invalidateCache(activePath));
}
use of io.pravega.controller.store.stream.tables.ActiveTxnRecord in project pravega by pravega.
the class ZKStream method createNewTransactionNode.
private CompletableFuture<Integer> createNewTransactionNode(final UUID txId, final long timestamp, final long leaseExpiryTime, final long maxExecutionExpiryTime, final long scaleGracePeriod) {
return getLatestEpoch().thenCompose(pair -> {
final String activePath = getActiveTxPath(pair.getKey(), txId.toString());
final byte[] txnRecord = new ActiveTxnRecord(timestamp, leaseExpiryTime, maxExecutionExpiryTime, scaleGracePeriod, TxnStatus.OPEN).toByteArray();
return store.createZNodeIfNotExist(activePath, txnRecord, false).thenApply(x -> cache.invalidateCache(activePath)).thenApply(y -> pair.getKey());
});
}
use of io.pravega.controller.store.stream.tables.ActiveTxnRecord in project pravega by pravega.
the class PersistentStreamBase method sealActiveTxn.
/**
* Seal a transaction in OPEN/COMMITTING/ABORTING state. This method does CAS on the transaction data node if
* the transaction is in OPEN state, optionally checking version of transaction data node, if required.
*
* @param epoch transaction epoch.
* @param txId transaction identifier.
* @param commit boolean indicating whether to commit or abort the transaction.
* @param version optional expected version of transaction node to validate before updating it.
* @return a pair containing transaction status and its epoch.
*/
private CompletableFuture<SimpleEntry<TxnStatus, Integer>> sealActiveTxn(final int epoch, final UUID txId, final boolean commit, final Optional<Integer> version) {
return getActiveTx(epoch, txId).thenCompose(data -> {
ActiveTxnRecord txnRecord = ActiveTxnRecord.parse(data.getData());
int dataVersion = version.isPresent() ? version.get() : data.getVersion();
TxnStatus status = txnRecord.getTxnStatus();
switch(status) {
case OPEN:
return sealActiveTx(epoch, txId, commit, txnRecord, dataVersion).thenApply(y -> new SimpleEntry<>(commit ? TxnStatus.COMMITTING : TxnStatus.ABORTING, epoch));
case COMMITTING:
case COMMITTED:
if (commit) {
return CompletableFuture.completedFuture(new SimpleEntry<>(status, epoch));
} else {
throw StoreException.create(StoreException.Type.ILLEGAL_STATE, "Stream: " + getName() + " Transaction: " + txId.toString() + " State: " + status.name());
}
case ABORTING:
case ABORTED:
if (commit) {
throw StoreException.create(StoreException.Type.ILLEGAL_STATE, "Stream: " + getName() + " Transaction: " + txId.toString() + " State: " + status.name());
} else {
return CompletableFuture.completedFuture(new SimpleEntry<>(status, epoch));
}
default:
throw StoreException.create(StoreException.Type.DATA_NOT_FOUND, "Stream: " + getName() + " Transaction: " + txId.toString());
}
});
}
Aggregations