Search in sources :

Example 1 with Data

use of io.pravega.controller.store.stream.tables.Data 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;
}
Also used : ActiveTxnRecord(io.pravega.controller.store.stream.tables.ActiveTxnRecord) CompletableFuture(java.util.concurrent.CompletableFuture) Data(io.pravega.controller.store.stream.tables.Data)

Example 2 with Data

use of io.pravega.controller.store.stream.tables.Data in project pravega by pravega.

the class PersistentStreamBase method addPartialHistoryRecord.

/**
 * update history table if not already updated:
 * fetch last record from history table.
 * if eventTime is >= scale.scaleTimeStamp do nothing, else create record
 *
 * @return : future of history table offset for last entry
 */
private CompletableFuture<Void> addPartialHistoryRecord(final List<Integer> sealedSegments, final List<Integer> createdSegments, final int epoch) {
    return getHistoryTable().thenCompose(historyTable -> {
        final Optional<HistoryRecord> lastRecordOpt = HistoryRecord.readLatestRecord(historyTable.getData(), false);
        // record in history table.
        assert lastRecordOpt.isPresent();
        final HistoryRecord lastRecord = lastRecordOpt.get();
        // idempotent check
        if (lastRecord.getEpoch() > epoch) {
            boolean idempotent = lastRecord.isPartial() && lastRecord.getSegments().containsAll(createdSegments);
            if (idempotent) {
                HistoryRecord previous = HistoryRecord.fetchPrevious(lastRecord, historyTable.getData()).get();
                idempotent = previous.getSegments().stream().noneMatch(createdSegments::contains);
            }
            if (idempotent) {
                log.debug("{}/{} scale op for epoch {} - history record already added", scope, name, epoch);
                return CompletableFuture.completedFuture(null);
            } else {
                log.warn("{}/{} scale op for epoch {}. Scale already completed.", scope, name, epoch);
                throw new ScaleOperationExceptions.ScaleConditionInvalidException();
            }
        }
        final List<Integer> newActiveSegments = getNewActiveSegments(createdSegments, sealedSegments, lastRecord);
        byte[] updatedTable = TableHelper.addPartialRecordToHistoryTable(historyTable.getData(), newActiveSegments);
        final Data<T> updated = new Data<>(updatedTable, historyTable.getVersion());
        int latestEpoch = TableHelper.getLatestEpoch(updatedTable).getKey();
        return createNewEpoch(latestEpoch).thenCompose(v -> updateHistoryTable(updated)).whenComplete((r, e) -> {
            if (e == null) {
                log.debug("{}/{} scale op for epoch {}. Creating new epoch and updating history table.", scope, name, epoch);
            } else {
                log.warn("{}/{} scale op for epoch {}. Failed to update history table. {}", scope, name, epoch, e.getClass().getName());
            }
        });
    });
}
Also used : IndexRecord(io.pravega.controller.store.stream.tables.IndexRecord) IntStream(java.util.stream.IntStream) CompletedTxnRecord(io.pravega.controller.store.stream.tables.CompletedTxnRecord) RetentionRecord(io.pravega.controller.store.stream.tables.RetentionRecord) SneakyThrows(lombok.SneakyThrows) Exceptions(io.pravega.common.Exceptions) SerializationUtils(org.apache.commons.lang3.SerializationUtils) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) SimpleImmutableEntry(java.util.AbstractMap.SimpleImmutableEntry) StreamConfiguration(io.pravega.client.stream.StreamConfiguration) BitConverter(io.pravega.common.util.BitConverter) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) Lists(com.google.common.collect.Lists) Pair(org.apache.commons.lang3.tuple.Pair) Collectors.toMap(java.util.stream.Collectors.toMap) Data(io.pravega.controller.store.stream.tables.Data) Map(java.util.Map) HistoryRecord(io.pravega.controller.store.stream.tables.HistoryRecord) TableHelper(io.pravega.controller.store.stream.tables.TableHelper) SimpleEntry(java.util.AbstractMap.SimpleEntry) TaskExceptions(io.pravega.controller.server.eventProcessor.requesthandlers.TaskExceptions) DataNotFoundException(io.pravega.controller.store.stream.StoreException.DataNotFoundException) ImmutableTriple(org.apache.commons.lang3.tuple.ImmutableTriple) StreamTruncationRecord(io.pravega.controller.store.stream.tables.StreamTruncationRecord) lombok.val(lombok.val) Set(java.util.Set) CompletionException(java.util.concurrent.CompletionException) UUID(java.util.UUID) State(io.pravega.controller.store.stream.tables.State) Collectors(java.util.stream.Collectors) ImmutablePair(org.apache.commons.lang3.tuple.ImmutablePair) Slf4j(lombok.extern.slf4j.Slf4j) AbstractMap(java.util.AbstractMap) List(java.util.List) SealedSegmentsRecord(io.pravega.controller.store.stream.tables.SealedSegmentsRecord) ActiveTxnRecord(io.pravega.controller.store.stream.tables.ActiveTxnRecord) Optional(java.util.Optional) Preconditions(com.google.common.base.Preconditions) Collections(java.util.Collections) Futures(io.pravega.common.concurrent.Futures) Data(io.pravega.controller.store.stream.tables.Data) HistoryRecord(io.pravega.controller.store.stream.tables.HistoryRecord)

Example 3 with Data

use of io.pravega.controller.store.stream.tables.Data in project pravega by pravega.

the class PersistentStreamBase method completeScale.

private CompletableFuture<Void> completeScale(final long scaleTimestamp, final Map<Integer, Long> sealedSegments, final int activeEpoch, final List<Integer> newSegments) {
    return getHistoryTable().thenCompose(historyTable -> {
        final Optional<HistoryRecord> lastRecordOpt = HistoryRecord.readLatestRecord(historyTable.getData(), false);
        assert lastRecordOpt.isPresent();
        final HistoryRecord lastRecord = lastRecordOpt.get();
        // idempotent check
        if (!lastRecord.isPartial()) {
            if (lastRecord.getSegments().stream().noneMatch(sealedSegments::containsKey) && newSegments.stream().allMatch(x -> lastRecord.getSegments().contains(x))) {
                log.debug("{}/{} scale already completed for epoch {}.", scope, name, activeEpoch);
                return CompletableFuture.completedFuture(null);
            } else {
                log.debug("{}/{} scale complete attempt invalid for epoch {}.", scope, name, activeEpoch);
                throw new ScaleOperationExceptions.ScaleConditionInvalidException();
            }
        }
        long scaleEventTime = Math.max(System.currentTimeMillis(), scaleTimestamp);
        final Optional<HistoryRecord> previousOpt = HistoryRecord.fetchPrevious(lastRecord, historyTable.getData());
        if (previousOpt.isPresent()) {
            // To ensure that we always have ascending time in history records irrespective of controller clock mismatches.
            scaleEventTime = Math.max(scaleEventTime, previousOpt.get().getScaleTime() + 1);
            if (previousOpt.get().getEpoch() > activeEpoch) {
                throw new ScaleOperationExceptions.ScaleConditionInvalidException();
            }
        }
        byte[] updatedTable = TableHelper.completePartialRecordInHistoryTable(historyTable.getData(), lastRecord, scaleEventTime);
        final Data<T> updated = new Data<>(updatedTable, historyTable.getVersion());
        final HistoryRecord newRecord = HistoryRecord.readLatestRecord(updatedTable, false).get();
        return addSealedSegmentsToRecord(sealedSegments).thenCompose(x -> addIndexRecord(newRecord)).thenCompose(x -> updateHistoryTable(updated)).thenCompose(x -> Futures.toVoid(updateState(State.ACTIVE))).whenComplete((r, e) -> {
            if (e != null) {
                log.warn("{}/{} attempt to complete scale for epoch {}. {}", scope, name, activeEpoch, e.getClass().getName());
            } else {
                log.debug("{}/{} scale complete, index and history tables updated for epoch {}.", scope, name, activeEpoch);
            }
        });
    });
}
Also used : IndexRecord(io.pravega.controller.store.stream.tables.IndexRecord) IntStream(java.util.stream.IntStream) CompletedTxnRecord(io.pravega.controller.store.stream.tables.CompletedTxnRecord) RetentionRecord(io.pravega.controller.store.stream.tables.RetentionRecord) SneakyThrows(lombok.SneakyThrows) Exceptions(io.pravega.common.Exceptions) SerializationUtils(org.apache.commons.lang3.SerializationUtils) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) SimpleImmutableEntry(java.util.AbstractMap.SimpleImmutableEntry) StreamConfiguration(io.pravega.client.stream.StreamConfiguration) BitConverter(io.pravega.common.util.BitConverter) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) Lists(com.google.common.collect.Lists) Pair(org.apache.commons.lang3.tuple.Pair) Collectors.toMap(java.util.stream.Collectors.toMap) Data(io.pravega.controller.store.stream.tables.Data) Map(java.util.Map) HistoryRecord(io.pravega.controller.store.stream.tables.HistoryRecord) TableHelper(io.pravega.controller.store.stream.tables.TableHelper) SimpleEntry(java.util.AbstractMap.SimpleEntry) TaskExceptions(io.pravega.controller.server.eventProcessor.requesthandlers.TaskExceptions) DataNotFoundException(io.pravega.controller.store.stream.StoreException.DataNotFoundException) ImmutableTriple(org.apache.commons.lang3.tuple.ImmutableTriple) StreamTruncationRecord(io.pravega.controller.store.stream.tables.StreamTruncationRecord) lombok.val(lombok.val) Set(java.util.Set) CompletionException(java.util.concurrent.CompletionException) UUID(java.util.UUID) State(io.pravega.controller.store.stream.tables.State) Collectors(java.util.stream.Collectors) ImmutablePair(org.apache.commons.lang3.tuple.ImmutablePair) Slf4j(lombok.extern.slf4j.Slf4j) AbstractMap(java.util.AbstractMap) List(java.util.List) SealedSegmentsRecord(io.pravega.controller.store.stream.tables.SealedSegmentsRecord) ActiveTxnRecord(io.pravega.controller.store.stream.tables.ActiveTxnRecord) Optional(java.util.Optional) Preconditions(com.google.common.base.Preconditions) Collections(java.util.Collections) Futures(io.pravega.common.concurrent.Futures) Data(io.pravega.controller.store.stream.tables.Data) HistoryRecord(io.pravega.controller.store.stream.tables.HistoryRecord)

Example 4 with Data

use of io.pravega.controller.store.stream.tables.Data 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));
}
Also used : ActiveTxnRecord(io.pravega.controller.store.stream.tables.ActiveTxnRecord) Data(io.pravega.controller.store.stream.tables.Data) UUID(java.util.UUID)

Example 5 with Data

use of io.pravega.controller.store.stream.tables.Data 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));
}
Also used : ActiveTxnRecord(io.pravega.controller.store.stream.tables.ActiveTxnRecord) CompletedTxnRecord(io.pravega.controller.store.stream.tables.CompletedTxnRecord) Getter(lombok.Getter) Exceptions(io.pravega.common.Exceptions) StreamTruncationRecord(io.pravega.controller.store.stream.tables.StreamTruncationRecord) Cache(io.pravega.controller.store.stream.tables.Cache) SerializationUtils(org.apache.commons.lang3.SerializationUtils) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) UUID(java.util.UUID) State(io.pravega.controller.store.stream.tables.State) StreamConfiguration(io.pravega.client.stream.StreamConfiguration) BitConverter(io.pravega.common.util.BitConverter) Collectors(java.util.stream.Collectors) ZKPaths(org.apache.curator.utils.ZKPaths) List(java.util.List) AccessLevel(lombok.AccessLevel) ActiveTxnRecord(io.pravega.controller.store.stream.tables.ActiveTxnRecord) Data(io.pravega.controller.store.stream.tables.Data) Map(java.util.Map) Optional(java.util.Optional) TableHelper(io.pravega.controller.store.stream.tables.TableHelper) Futures(io.pravega.common.concurrent.Futures) Data(io.pravega.controller.store.stream.tables.Data)

Aggregations

Data (io.pravega.controller.store.stream.tables.Data)7 CompletableFuture (java.util.concurrent.CompletableFuture)6 ActiveTxnRecord (io.pravega.controller.store.stream.tables.ActiveTxnRecord)5 List (java.util.List)5 Collectors (java.util.stream.Collectors)5 StreamConfiguration (io.pravega.client.stream.StreamConfiguration)4 State (io.pravega.controller.store.stream.tables.State)4 Map (java.util.Map)4 UUID (java.util.UUID)4 SerializationUtils (org.apache.commons.lang3.SerializationUtils)4 Preconditions (com.google.common.base.Preconditions)3 Lists (com.google.common.collect.Lists)3 Exceptions (io.pravega.common.Exceptions)3 Futures (io.pravega.common.concurrent.Futures)3 BitConverter (io.pravega.common.util.BitConverter)3 CompletedTxnRecord (io.pravega.controller.store.stream.tables.CompletedTxnRecord)3 StreamTruncationRecord (io.pravega.controller.store.stream.tables.StreamTruncationRecord)3 TableHelper (io.pravega.controller.store.stream.tables.TableHelper)3 AbstractMap (java.util.AbstractMap)3 ArrayList (java.util.ArrayList)3