Search in sources :

Example 31 with VersionedMetadata

use of io.pravega.controller.store.VersionedMetadata in project pravega by pravega.

the class PersistentStreamBase method submitScale.

/**
 * This method attempts to start a new scale workflow. For this it first computes epoch transition and stores it
 * in the metadastore.
 * This method can be called by manual scale or during the processing of auto-scale event. Which means there could be
 * concurrent calls to this method.
 *
 * @param segmentsToSeal segments that will be sealed at the end of this scale operation.
 * @param newRanges      key ranges of new segments to be created
 * @param scaleTimestamp scaling timestamp
 * @return : list of newly created segments with current epoch
 */
@Override
public CompletableFuture<VersionedMetadata<EpochTransitionRecord>> submitScale(final List<Long> segmentsToSeal, final List<Map.Entry<Double, Double>> newRanges, final long scaleTimestamp, final VersionedMetadata<EpochTransitionRecord> existing, OperationContext context) {
    Preconditions.checkNotNull(context, "Operation context cannot be null");
    return verifyNotSealed(context).thenCompose(v -> {
        if (existing == null) {
            return getEpochTransition(context);
        } else {
            return CompletableFuture.completedFuture(existing);
        }
    }).thenCompose(record -> getActiveEpochRecord(true, context).thenCompose(currentEpoch -> getConfiguration(context).thenCompose(config -> {
        if (!record.getObject().equals(EpochTransitionRecord.EMPTY)) {
            // and new ranges are identical). else throw scale conflict exception
            if (!RecordHelper.verifyRecordMatchesInput(segmentsToSeal, newRanges, false, record.getObject())) {
                log.debug(context.getRequestId(), "scale conflict, another scale operation is ongoing");
                throw new EpochTransitionOperationExceptions.ConflictException();
            }
            return CompletableFuture.completedFuture(record);
        } else {
            // check input is valid and satisfies preconditions
            if (!RecordHelper.canScaleFor(segmentsToSeal, currentEpoch)) {
                return updateEpochTransitionNode(new VersionedMetadata<>(EpochTransitionRecord.EMPTY, record.getVersion()), context).thenApply(x -> {
                    log.warn(context.getRequestId(), "scale precondition failed {}", segmentsToSeal);
                    throw new EpochTransitionOperationExceptions.PreConditionFailureException();
                });
            }
            if (!RecordHelper.validateInputRange(segmentsToSeal, newRanges, currentEpoch)) {
                log.error(context.getRequestId(), "scale input invalid {} {}", segmentsToSeal, newRanges);
                throw new EpochTransitionOperationExceptions.InputInvalidException();
            }
            int numberOfSegmentsPostScale = currentEpoch.getSegments().size() - segmentsToSeal.size() + newRanges.size();
            if (numberOfSegmentsPostScale < config.getScalingPolicy().getMinNumSegments()) {
                log.warn(context.getRequestId(), "Scale cannot be performed as Min Segment Count will not hold {} {}", segmentsToSeal, newRanges);
                throw new EpochTransitionOperationExceptions.PreConditionFailureException();
            }
            EpochTransitionRecord epochTransition = RecordHelper.computeEpochTransition(currentEpoch, segmentsToSeal, newRanges, scaleTimestamp);
            return updateEpochTransitionNode(new VersionedMetadata<>(epochTransition, record.getVersion()), context).thenApply(version -> {
                log.info(context.getRequestId(), "scale for stream {}/{} accepted. Segments to seal = {}", scope, name, epochTransition.getSegmentsToSeal());
                return new VersionedMetadata<>(epochTransition, version);
            });
        }
    })));
}
Also used : StreamSegmentRecord(io.pravega.controller.store.stream.records.StreamSegmentRecord) SneakyThrows(lombok.SneakyThrows) BiFunction(java.util.function.BiFunction) LoggerFactory(org.slf4j.LoggerFactory) StreamConfiguration(io.pravega.client.stream.StreamConfiguration) TagLogger(io.pravega.common.tracing.TagLogger) VersionedMetadata(io.pravega.controller.store.VersionedMetadata) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) DataNotFoundException(io.pravega.controller.store.stream.StoreException.DataNotFoundException) EpochTransitionRecord(io.pravega.controller.store.stream.records.EpochTransitionRecord) ImmutableSet(com.google.common.collect.ImmutableSet) StreamCutReferenceRecord(io.pravega.controller.store.stream.records.StreamCutReferenceRecord) StreamTruncationRecord(io.pravega.controller.store.stream.records.StreamTruncationRecord) ImmutableMap(com.google.common.collect.ImmutableMap) Predicate(java.util.function.Predicate) Collection(java.util.Collection) Set(java.util.Set) CompletionException(java.util.concurrent.CompletionException) ActiveTxnRecord(io.pravega.controller.store.stream.records.ActiveTxnRecord) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) List(java.util.List) CompletionStage(java.util.concurrent.CompletionStage) Optional(java.util.Optional) HistoryTimeSeries(io.pravega.controller.store.stream.records.HistoryTimeSeries) Futures(io.pravega.common.concurrent.Futures) IntStream(java.util.stream.IntStream) CompletedTxnRecord(io.pravega.controller.store.stream.records.CompletedTxnRecord) CommittingTransactionsRecord(io.pravega.controller.store.stream.records.CommittingTransactionsRecord) NameUtils.computeSegmentId(io.pravega.shared.NameUtils.computeSegmentId) Exceptions(io.pravega.common.Exceptions) HistoryTimeSeriesRecord(io.pravega.controller.store.stream.records.HistoryTimeSeriesRecord) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) RetentionSet(io.pravega.controller.store.stream.records.RetentionSet) DATA_NOT_FOUND_PREDICATE(io.pravega.controller.store.stream.AbstractStreamMetadataStore.DATA_NOT_FOUND_PREDICATE) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) NameUtils.getSegmentNumber(io.pravega.shared.NameUtils.getSegmentNumber) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) StateRecord(io.pravega.controller.store.stream.records.StateRecord) StreamSubscriber(io.pravega.controller.store.stream.records.StreamSubscriber) LinkedList(java.util.LinkedList) RecordHelper(io.pravega.controller.store.stream.records.RecordHelper) SimpleEntry(java.util.AbstractMap.SimpleEntry) LongSummaryStatistics(java.util.LongSummaryStatistics) CollectionHelpers(io.pravega.common.util.CollectionHelpers) SealedSegmentsMapShard(io.pravega.controller.store.stream.records.SealedSegmentsMapShard) NameUtils(io.pravega.shared.NameUtils) Executor(java.util.concurrent.Executor) WriterMark(io.pravega.controller.store.stream.records.WriterMark) lombok.val(lombok.val) StreamCutRecord(io.pravega.controller.store.stream.records.StreamCutRecord) AtomicLong(java.util.concurrent.atomic.AtomicLong) StreamConfigurationRecord(io.pravega.controller.store.stream.records.StreamConfigurationRecord) EpochRecord(io.pravega.controller.store.stream.records.EpochRecord) ConcurrentSkipListSet(java.util.concurrent.ConcurrentSkipListSet) Version(io.pravega.controller.store.Version) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Comparator(java.util.Comparator) Collections(java.util.Collections) EpochTransitionRecord(io.pravega.controller.store.stream.records.EpochTransitionRecord) VersionedMetadata(io.pravega.controller.store.VersionedMetadata)

Example 32 with VersionedMetadata

use of io.pravega.controller.store.VersionedMetadata in project pravega by pravega.

the class PersistentStreamBase method completeTruncation.

@Override
public CompletableFuture<Void> completeTruncation(VersionedMetadata<StreamTruncationRecord> record, OperationContext context) {
    Preconditions.checkNotNull(context, "operation context cannot be null");
    Preconditions.checkNotNull(record);
    Preconditions.checkArgument(record.getObject().isUpdating());
    StreamTruncationRecord current = record.getObject();
    if (current.isUpdating()) {
        StreamTruncationRecord completedProp = StreamTruncationRecord.complete(current);
        return Futures.toVoid(setTruncationData(new VersionedMetadata<>(completedProp, record.getVersion()), context));
    } else {
        // idempotent
        return CompletableFuture.completedFuture(null);
    }
}
Also used : StreamTruncationRecord(io.pravega.controller.store.stream.records.StreamTruncationRecord) VersionedMetadata(io.pravega.controller.store.VersionedMetadata)

Example 33 with VersionedMetadata

use of io.pravega.controller.store.VersionedMetadata in project pravega by pravega.

the class PersistentStreamBase method scaleCreateNewEpoch.

@Override
public CompletableFuture<VersionedMetadata<EpochTransitionRecord>> scaleCreateNewEpoch(VersionedMetadata<EpochTransitionRecord> versionedMetadata, OperationContext context) {
    Preconditions.checkNotNull(context, "Operation context cannot be null");
    return getActiveEpochRecord(true, context).thenCompose(currentEpoch -> {
        // only perform idempotent update. If update is already completed, do nothing.
        if (currentEpoch.getEpoch() < versionedMetadata.getObject().getNewEpoch()) {
            EpochTransitionRecord epochTransition = versionedMetadata.getObject();
            // time
            long time = Math.max(epochTransition.getTime(), currentEpoch.getCreationTime() + 1);
            // new segments
            ImmutableList.Builder<StreamSegmentRecord> newSegmentsBuilder = ImmutableList.builder();
            epochTransition.getNewSegmentsWithRange().forEach((key, value) -> newSegmentsBuilder.add(newSegmentRecord(key, time, value.getKey(), value.getValue())));
            // sealed segments
            ImmutableList.Builder<StreamSegmentRecord> sealedSegmentsBuilder = ImmutableList.builder();
            epochTransition.getSegmentsToSeal().forEach(x -> sealedSegmentsBuilder.add(currentEpoch.getSegment(x)));
            // overall segments in epoch
            ImmutableList.Builder<StreamSegmentRecord> builder = ImmutableList.builder();
            currentEpoch.getSegments().forEach(x -> {
                if (!epochTransition.getSegmentsToSeal().contains(x.segmentId())) {
                    builder.add(x);
                }
            });
            ImmutableList<StreamSegmentRecord> newSegments = newSegmentsBuilder.build();
            builder.addAll(newSegments);
            ImmutableList<StreamSegmentRecord> newEpochSegments = builder.build();
            // epoch record
            return getSplitMergeCountsTillEpoch(currentEpoch, context).thenCompose(cumulativeSplitMergeCount -> {
                EpochRecord epochRecord = new EpochRecord(epochTransition.getNewEpoch(), epochTransition.getNewEpoch(), newEpochSegments, time, getNewEpochSplitCount(cumulativeSplitMergeCount.getKey(), currentEpoch.getSegments(), newEpochSegments), getNewEpochMergeCount(cumulativeSplitMergeCount.getValue(), currentEpoch.getSegments(), newEpochSegments));
                HistoryTimeSeriesRecord timeSeriesRecord = new HistoryTimeSeriesRecord(epochTransition.getNewEpoch(), epochTransition.getNewEpoch(), sealedSegmentsBuilder.build(), newSegments, epochRecord.getCreationTime());
                return createEpochRecord(epochRecord, context).thenCompose(x -> updateHistoryTimeSeries(timeSeriesRecord, context)).thenCompose(x -> createSegmentSealedEpochRecords(epochTransition.getSegmentsToSeal(), epochTransition.getNewEpoch(), context)).thenApply(x -> versionedMetadata);
            });
        } else {
            return CompletableFuture.completedFuture(versionedMetadata);
        }
    });
}
Also used : StreamSegmentRecord(io.pravega.controller.store.stream.records.StreamSegmentRecord) SneakyThrows(lombok.SneakyThrows) BiFunction(java.util.function.BiFunction) LoggerFactory(org.slf4j.LoggerFactory) StreamConfiguration(io.pravega.client.stream.StreamConfiguration) TagLogger(io.pravega.common.tracing.TagLogger) VersionedMetadata(io.pravega.controller.store.VersionedMetadata) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) DataNotFoundException(io.pravega.controller.store.stream.StoreException.DataNotFoundException) EpochTransitionRecord(io.pravega.controller.store.stream.records.EpochTransitionRecord) ImmutableSet(com.google.common.collect.ImmutableSet) StreamCutReferenceRecord(io.pravega.controller.store.stream.records.StreamCutReferenceRecord) StreamTruncationRecord(io.pravega.controller.store.stream.records.StreamTruncationRecord) ImmutableMap(com.google.common.collect.ImmutableMap) Predicate(java.util.function.Predicate) Collection(java.util.Collection) Set(java.util.Set) CompletionException(java.util.concurrent.CompletionException) ActiveTxnRecord(io.pravega.controller.store.stream.records.ActiveTxnRecord) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) List(java.util.List) CompletionStage(java.util.concurrent.CompletionStage) Optional(java.util.Optional) HistoryTimeSeries(io.pravega.controller.store.stream.records.HistoryTimeSeries) Futures(io.pravega.common.concurrent.Futures) IntStream(java.util.stream.IntStream) CompletedTxnRecord(io.pravega.controller.store.stream.records.CompletedTxnRecord) CommittingTransactionsRecord(io.pravega.controller.store.stream.records.CommittingTransactionsRecord) NameUtils.computeSegmentId(io.pravega.shared.NameUtils.computeSegmentId) Exceptions(io.pravega.common.Exceptions) HistoryTimeSeriesRecord(io.pravega.controller.store.stream.records.HistoryTimeSeriesRecord) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) RetentionSet(io.pravega.controller.store.stream.records.RetentionSet) DATA_NOT_FOUND_PREDICATE(io.pravega.controller.store.stream.AbstractStreamMetadataStore.DATA_NOT_FOUND_PREDICATE) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) NameUtils.getSegmentNumber(io.pravega.shared.NameUtils.getSegmentNumber) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) StateRecord(io.pravega.controller.store.stream.records.StateRecord) StreamSubscriber(io.pravega.controller.store.stream.records.StreamSubscriber) LinkedList(java.util.LinkedList) RecordHelper(io.pravega.controller.store.stream.records.RecordHelper) SimpleEntry(java.util.AbstractMap.SimpleEntry) LongSummaryStatistics(java.util.LongSummaryStatistics) CollectionHelpers(io.pravega.common.util.CollectionHelpers) SealedSegmentsMapShard(io.pravega.controller.store.stream.records.SealedSegmentsMapShard) NameUtils(io.pravega.shared.NameUtils) Executor(java.util.concurrent.Executor) WriterMark(io.pravega.controller.store.stream.records.WriterMark) lombok.val(lombok.val) StreamCutRecord(io.pravega.controller.store.stream.records.StreamCutRecord) AtomicLong(java.util.concurrent.atomic.AtomicLong) StreamConfigurationRecord(io.pravega.controller.store.stream.records.StreamConfigurationRecord) EpochRecord(io.pravega.controller.store.stream.records.EpochRecord) ConcurrentSkipListSet(java.util.concurrent.ConcurrentSkipListSet) Version(io.pravega.controller.store.Version) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Comparator(java.util.Comparator) Collections(java.util.Collections) StreamSegmentRecord(io.pravega.controller.store.stream.records.StreamSegmentRecord) EpochRecord(io.pravega.controller.store.stream.records.EpochRecord) EpochTransitionRecord(io.pravega.controller.store.stream.records.EpochTransitionRecord) HistoryTimeSeriesRecord(io.pravega.controller.store.stream.records.HistoryTimeSeriesRecord) ImmutableList(com.google.common.collect.ImmutableList)

Example 34 with VersionedMetadata

use of io.pravega.controller.store.VersionedMetadata in project pravega by pravega.

the class PersistentStreamBase method updateHistoryTimeSeries.

private CompletableFuture<Void> updateHistoryTimeSeries(HistoryTimeSeriesRecord record, OperationContext context) {
    int historyChunk = record.getEpoch() / historyChunkSize.get();
    boolean isFirst = record.getEpoch() % historyChunkSize.get() == 0;
    if (isFirst) {
        return createHistoryTimeSeriesChunk(historyChunk, record, context);
    } else {
        return getHistoryTimeSeriesChunkData(historyChunk, true, context).thenCompose(x -> {
            HistoryTimeSeries historyChunkTimeSeries = x.getObject();
            if (historyChunkTimeSeries.getLatestRecord().getEpoch() < record.getEpoch()) {
                HistoryTimeSeries update = HistoryTimeSeries.addHistoryRecord(historyChunkTimeSeries, record);
                return Futures.toVoid(updateHistoryTimeSeriesChunkData(historyChunk, new VersionedMetadata<>(update, x.getVersion()), context));
            } else {
                return CompletableFuture.completedFuture(null);
            }
        });
    }
}
Also used : VersionedMetadata(io.pravega.controller.store.VersionedMetadata) HistoryTimeSeries(io.pravega.controller.store.stream.records.HistoryTimeSeries)

Example 35 with VersionedMetadata

use of io.pravega.controller.store.VersionedMetadata in project pravega by pravega.

the class PersistentStreamBase method pingTransaction.

@Override
public CompletableFuture<VersionedTransactionData> pingTransaction(final VersionedTransactionData txnData, final long lease, OperationContext context) {
    Preconditions.checkNotNull(context, "Operation context cannot be null");
    // Update txn record with new lease value and return versioned tx data.
    final int epoch = txnData.getEpoch();
    final UUID txnId = txnData.getId();
    final Version version = txnData.getVersion();
    final long creationTime = txnData.getCreationTime();
    final long maxExecutionExpiryTime = txnData.getMaxExecutionExpiryTime();
    final TxnStatus status = txnData.getStatus();
    final String writerId = txnData.getWriterId();
    final long commitTime = txnData.getCommitTime();
    final long position = txnData.getCommitOrder();
    final ImmutableMap<Long, Long> commitOffsets = txnData.getCommitOffsets();
    final ActiveTxnRecord newData = new ActiveTxnRecord(creationTime, System.currentTimeMillis() + lease, maxExecutionExpiryTime, status, writerId, commitTime, position, commitOffsets);
    final VersionedMetadata<ActiveTxnRecord> data = new VersionedMetadata<>(newData, version);
    return updateActiveTx(epoch, txnId, data, context).thenApply(updatedVersion -> new VersionedTransactionData(epoch, txnId, updatedVersion, status, creationTime, maxExecutionExpiryTime, writerId, commitTime, position, commitOffsets));
}
Also used : ActiveTxnRecord(io.pravega.controller.store.stream.records.ActiveTxnRecord) Version(io.pravega.controller.store.Version) AtomicLong(java.util.concurrent.atomic.AtomicLong) UUID(java.util.UUID) VersionedMetadata(io.pravega.controller.store.VersionedMetadata)

Aggregations

VersionedMetadata (io.pravega.controller.store.VersionedMetadata)45 Map (java.util.Map)32 Futures (io.pravega.common.concurrent.Futures)31 List (java.util.List)31 Collectors (java.util.stream.Collectors)31 ArrayList (java.util.ArrayList)30 StreamConfiguration (io.pravega.client.stream.StreamConfiguration)29 EpochTransitionRecord (io.pravega.controller.store.stream.records.EpochTransitionRecord)29 StreamConfigurationRecord (io.pravega.controller.store.stream.records.StreamConfigurationRecord)29 UUID (java.util.UUID)28 CompletableFuture (java.util.concurrent.CompletableFuture)28 EpochRecord (io.pravega.controller.store.stream.records.EpochRecord)27 Exceptions (io.pravega.common.Exceptions)26 NameUtils (io.pravega.shared.NameUtils)26 StreamTruncationRecord (io.pravega.controller.store.stream.records.StreamTruncationRecord)25 HashMap (java.util.HashMap)25 ImmutableMap (com.google.common.collect.ImmutableMap)24 NameUtils.computeSegmentId (io.pravega.shared.NameUtils.computeSegmentId)24 Collections (java.util.Collections)24 Optional (java.util.Optional)24