Search in sources :

Example 1 with EpochRecord

use of io.pravega.controller.store.stream.records.EpochRecord in project pravega by pravega.

the class CommitRequestHandler method tryCommitTransactions.

/**
 * Try creating txn commit list first. if node already exists and doesn't match the processing in the event, throw
 * operation not allowed.
 * This will result in event being posted back in the stream and retried later. Generally if a transaction commit starts,
 * it will come to an end. However, during failover, once we have created the node, we are guaranteed that it will
 * be only that transaction that will be getting committed at that time.
 * @return CompletableFuture which when completed will contain the epoch on which transactions were committed.
 */
private CompletableFuture<Integer> tryCommitTransactions(final String scope, final String stream, final OperationContext context) {
    Timer timer = new Timer();
    Map<String, TxnWriterMark> writerMarks = new HashMap<>();
    Map<UUID, String> txnIdToWriterId = new HashMap<>();
    return streamMetadataStore.getVersionedState(scope, stream, context, executor).thenComposeAsync(state -> {
        final AtomicReference<VersionedMetadata<State>> stateRecord = new AtomicReference<>(state);
        CompletableFuture<VersionedMetadata<CommittingTransactionsRecord>> commitFuture = streamMetadataStore.startCommitTransactions(scope, stream, MAX_TRANSACTION_COMMIT_BATCH_SIZE, context, executor).thenComposeAsync(txnsTuple -> {
            VersionedMetadata<CommittingTransactionsRecord> committingTxnsRecord = txnsTuple.getKey();
            if (committingTxnsRecord.getObject().equals(CommittingTransactionsRecord.EMPTY)) {
                // completed all the work.
                return CompletableFuture.completedFuture(committingTxnsRecord);
            } else {
                int txnEpoch = committingTxnsRecord.getObject().getEpoch();
                List<UUID> txnList = committingTxnsRecord.getObject().getTransactionsToCommit();
                log.info(context.getRequestId(), "Committing {} transactions on epoch {} on stream {}/{}", txnList, txnEpoch, scope, stream);
                // Once state is set to committing, we are guaranteed that this will be the only
                // processing that can happen on the stream and we can proceed with committing
                // outstanding transactions collected in the txnList step.
                CompletableFuture<Void> future;
                // completion of transactions in commit state.
                if (state.getObject().equals(State.SEALING)) {
                    future = CompletableFuture.completedFuture(null);
                } else {
                    // If state is not SEALING, try to set the state to COMMITTING_TXN before proceeding.
                    // If we are unable to set the state to COMMITTING_TXN, it will get OPERATION_NOT_ALLOWED
                    // and the processing will be retried later.
                    future = streamMetadataStore.updateVersionedState(scope, stream, State.COMMITTING_TXN, state, context, executor).thenAccept(stateRecord::set);
                }
                txnsTuple.getValue().forEach(txn -> {
                    if (!Strings.isNullOrEmpty(txn.getWriterId())) {
                        txnIdToWriterId.put(txn.getId(), txn.getWriterId());
                        if (!writerMarks.containsKey(txn.getWriterId()) || writerMarks.get(txn.getWriterId()).getTimestamp() < txn.getCommitTime()) {
                            writerMarks.put(txn.getWriterId(), new TxnWriterMark(txn.getCommitTime(), ImmutableMap.of(), txn.getId()));
                        }
                    }
                });
                // TxnCommittingRecord ensures no other rollingTxn can run concurrently
                return future.thenCompose(v -> getEpochRecords(scope, stream, txnEpoch, context).thenCompose(records -> {
                    EpochRecord txnEpochRecord = records.get(0);
                    EpochRecord activeEpochRecord = records.get(1);
                    CommitTxnContext commitContext = new CommitTxnContext(scope, stream, context, txnIdToWriterId, writerMarks);
                    if (activeEpochRecord.getEpoch() == txnEpoch || activeEpochRecord.getReferenceEpoch() == txnEpochRecord.getReferenceEpoch()) {
                        // we can commit transactions immediately
                        return commitTransactions(commitContext, committingTxnsRecord, activeEpochRecord.getSegmentIds().stream().collect(Collectors.toList())).thenApply(txnOffsets -> committingTxnsRecord);
                    } else {
                        return rollTransactions(commitContext, committingTxnsRecord, txnEpochRecord, activeEpochRecord);
                    }
                }));
            }
        }, executor);
        // reset state to ACTIVE if it was COMMITTING_TXN
        return commitFuture.thenCompose(committingTxnsRecord -> streamMetadataStore.completeCommitTransactions(scope, stream, committingTxnsRecord, context, executor, writerMarks).thenCompose(v -> resetStateConditionally(scope, stream, stateRecord.get(), context)).thenRun(() -> TransactionMetrics.getInstance().commitTransaction(scope, stream, timer.getElapsed())).thenApply(v -> committingTxnsRecord.getObject().getEpoch()));
    }, executor);
}
Also used : CommitEvent(io.pravega.shared.controller.event.CommitEvent) OperationContext(io.pravega.controller.store.stream.OperationContext) TransactionMetrics(io.pravega.controller.metrics.TransactionMetrics) CommittingTransactionsRecord(io.pravega.controller.store.stream.records.CommittingTransactionsRecord) NameUtils.computeSegmentId(io.pravega.shared.NameUtils.computeSegmentId) Exceptions(io.pravega.common.Exceptions) LoggerFactory(org.slf4j.LoggerFactory) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) BucketStore(io.pravega.controller.store.stream.BucketStore) TagLogger(io.pravega.common.tracing.TagLogger) VersionedMetadata(io.pravega.controller.store.VersionedMetadata) StoreException(io.pravega.controller.store.stream.StoreException) Map(java.util.Map) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) StreamMetadataTasks(io.pravega.controller.task.Stream.StreamMetadataTasks) ImmutableMap(com.google.common.collect.ImmutableMap) lombok.val(lombok.val) BlockingQueue(java.util.concurrent.BlockingQueue) UUID(java.util.UUID) Strings(org.apache.curator.shaded.com.google.common.base.Strings) Timer(io.pravega.common.Timer) Collectors(java.util.stream.Collectors) List(java.util.List) EpochRecord(io.pravega.controller.store.stream.records.EpochRecord) TxnWriterMark(io.pravega.controller.store.stream.TxnWriterMark) StreamTransactionMetadataTasks(io.pravega.controller.task.Stream.StreamTransactionMetadataTasks) Preconditions(com.google.common.base.Preconditions) State(io.pravega.controller.store.stream.State) VisibleForTesting(com.google.common.annotations.VisibleForTesting) StreamMetadataStore(io.pravega.controller.store.stream.StreamMetadataStore) AllArgsConstructor(lombok.AllArgsConstructor) ScalingPolicy(io.pravega.client.stream.ScalingPolicy) Futures(io.pravega.common.concurrent.Futures) TxnWriterMark(io.pravega.controller.store.stream.TxnWriterMark) EpochRecord(io.pravega.controller.store.stream.records.EpochRecord) HashMap(java.util.HashMap) CommittingTransactionsRecord(io.pravega.controller.store.stream.records.CommittingTransactionsRecord) AtomicReference(java.util.concurrent.atomic.AtomicReference) Timer(io.pravega.common.Timer) UUID(java.util.UUID) VersionedMetadata(io.pravega.controller.store.VersionedMetadata)

Example 2 with EpochRecord

use of io.pravega.controller.store.stream.records.EpochRecord in project pravega by pravega.

the class PersistentStreamBase method computeStreamCutSpanInternal.

private ImmutableMap<StreamSegmentRecord, Integer> computeStreamCutSpanInternal(Map<Long, Long> streamCut, int epochLow, int epochHigh, List<EpochRecord> epochs) {
    List<Long> toFind = new ArrayList<>(streamCut.keySet());
    ImmutableMap.Builder<StreamSegmentRecord, Integer> resultSet = ImmutableMap.builder();
    for (int i = epochHigh - epochLow; i >= 0; i--) {
        if (toFind.isEmpty()) {
            break;
        }
        EpochRecord epochRecord = epochs.get(i);
        Set<Long> epochSegments = epochRecord.getSegmentIds();
        List<Long> found = toFind.stream().filter(epochSegments::contains).collect(Collectors.toList());
        resultSet.putAll(found.stream().collect(Collectors.toMap(x -> epochRecord.getSegments().stream().filter(z -> z.segmentId() == x).findFirst().get(), x -> epochRecord.getEpoch())));
        toFind.removeAll(epochSegments);
    }
    return resultSet.build();
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) 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) AtomicLong(java.util.concurrent.atomic.AtomicLong) ArrayList(java.util.ArrayList) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 3 with EpochRecord

use of io.pravega.controller.store.stream.records.EpochRecord in project pravega by pravega.

the class PersistentStreamBase method rollingTxnCreateDuplicateEpochs.

@Override
public CompletableFuture<Void> rollingTxnCreateDuplicateEpochs(Map<Long, Long> sealedTxnEpochSegments, long time, VersionedMetadata<CommittingTransactionsRecord> record, OperationContext context) {
    Preconditions.checkNotNull(context, "Operation context cannot be null");
    Preconditions.checkArgument(record.getObject().isRollingTxnRecord());
    CommittingTransactionsRecord committingTxnRecord = record.getObject();
    return getActiveEpoch(true, context).thenCompose(activeEpochRecord -> getEpochRecord(committingTxnRecord.getEpoch(), context).thenCompose(transactionEpochRecord -> {
        if (activeEpochRecord.getEpoch() > committingTxnRecord.getCurrentEpoch()) {
            log.debug(context.getRequestId(), "Duplicate Epochs {} already created. Ignore.", committingTxnRecord.getNewActiveEpoch());
            return CompletableFuture.completedFuture(null);
        }
        long timeStamp = Math.max(activeEpochRecord.getCreationTime() + 1, time);
        ImmutableList.Builder<StreamSegmentRecord> duplicateTxnSegmentsBuilder = ImmutableList.builder();
        transactionEpochRecord.getSegments().stream().forEach(x -> duplicateTxnSegmentsBuilder.add(newSegmentRecord(computeSegmentId(getSegmentNumber(x.segmentId()), committingTxnRecord.getNewTxnEpoch()), timeStamp, x.getKeyStart(), x.getKeyEnd())));
        ImmutableList.Builder<StreamSegmentRecord> duplicateActiveSegmentsBuilder = ImmutableList.builder();
        activeEpochRecord.getSegments().stream().forEach(x -> duplicateActiveSegmentsBuilder.add(newSegmentRecord(computeSegmentId(getSegmentNumber(x.segmentId()), committingTxnRecord.getNewActiveEpoch()), timeStamp + 1, x.getKeyStart(), x.getKeyEnd())));
        CompletableFuture<EpochRecord> txnEpochFuture = getSplitMergeCountsTillEpoch(activeEpochRecord, context).thenCompose(txnSplitMergeCount -> {
            ImmutableList<StreamSegmentRecord> duplicateTxnEpochSegments = duplicateTxnSegmentsBuilder.build();
            EpochRecord duplicateTxnEpoch = new EpochRecord(committingTxnRecord.getNewTxnEpoch(), transactionEpochRecord.getReferenceEpoch(), duplicateTxnEpochSegments, timeStamp, getNewEpochSplitCount(txnSplitMergeCount.getKey(), activeEpochRecord.getSegments(), duplicateTxnEpochSegments), getNewEpochMergeCount(txnSplitMergeCount.getValue(), activeEpochRecord.getSegments(), duplicateTxnEpochSegments));
            return CompletableFuture.completedFuture(duplicateTxnEpoch);
        });
        CompletableFuture<EpochRecord> activeEpochFuture = txnEpochFuture.thenCompose(previousEpoch -> getSplitMergeCountsTillEpoch(previousEpoch, context).thenCompose(prevSplitMergeCounts -> {
            ImmutableList<StreamSegmentRecord> activeEpochSegments = duplicateActiveSegmentsBuilder.build();
            EpochRecord duplicateActiveEpoch = new EpochRecord(committingTxnRecord.getNewActiveEpoch(), activeEpochRecord.getReferenceEpoch(), activeEpochSegments, timeStamp + 1, getNewEpochSplitCount(prevSplitMergeCounts.getKey(), previousEpoch.getSegments(), activeEpochSegments), getNewEpochMergeCount(prevSplitMergeCounts.getValue(), previousEpoch.getSegments(), activeEpochSegments));
            return CompletableFuture.completedFuture(duplicateActiveEpoch);
        }));
        return CompletableFuture.allOf(txnEpochFuture, activeEpochFuture).thenCompose(v -> {
            EpochRecord duplicateTxnEpoch = txnEpochFuture.join();
            EpochRecord duplicateActiveEpoch = activeEpochFuture.join();
            HistoryTimeSeriesRecord timeSeriesRecordTxnEpoch = new HistoryTimeSeriesRecord(duplicateTxnEpoch.getEpoch(), duplicateTxnEpoch.getReferenceEpoch(), ImmutableList.of(), ImmutableList.of(), timeStamp);
            HistoryTimeSeriesRecord timeSeriesRecordActiveEpoch = new HistoryTimeSeriesRecord(duplicateActiveEpoch.getEpoch(), duplicateActiveEpoch.getReferenceEpoch(), ImmutableList.of(), ImmutableList.of(), timeStamp + 1);
            return createEpochRecord(duplicateTxnEpoch, context).thenCompose(x -> updateHistoryTimeSeries(timeSeriesRecordTxnEpoch, context)).thenCompose(x -> createEpochRecord(duplicateActiveEpoch, context)).thenCompose(x -> updateHistoryTimeSeries(timeSeriesRecordActiveEpoch, context)).thenCompose(x -> createSegmentSealedEpochRecords(activeEpochRecord.getSegments().stream().map(StreamSegmentRecord::segmentId).collect(Collectors.toList()), duplicateTxnEpoch.getEpoch(), context)).thenCompose(x -> createSegmentSealedEpochRecords(duplicateTxnEpoch.getSegments().stream().map(StreamSegmentRecord::segmentId).collect(Collectors.toList()), duplicateActiveEpoch.getEpoch(), context));
        }).thenCompose(r -> updateSealedSegmentSizes(sealedTxnEpochSegments, context));
    }));
}
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) CompletableFuture(java.util.concurrent.CompletableFuture) EpochRecord(io.pravega.controller.store.stream.records.EpochRecord) HistoryTimeSeriesRecord(io.pravega.controller.store.stream.records.HistoryTimeSeriesRecord) CommittingTransactionsRecord(io.pravega.controller.store.stream.records.CommittingTransactionsRecord) ImmutableList(com.google.common.collect.ImmutableList)

Example 4 with EpochRecord

use of io.pravega.controller.store.stream.records.EpochRecord in project pravega by pravega.

the class PersistentStreamBase method createHistoryRecords.

private CompletionStage<Void> createHistoryRecords(int startingSegmentNumber, CreateStreamResponse createStreamResponse, OperationContext context) {
    Preconditions.checkNotNull(context, "operation context cannot be null");
    final int numSegments = createStreamResponse.getConfiguration().getScalingPolicy().getMinNumSegments();
    // create epoch 0 record
    final double keyRangeChunk = 1.0 / numSegments;
    long creationTime = createStreamResponse.getTimestamp();
    final ImmutableList.Builder<StreamSegmentRecord> builder = ImmutableList.builder();
    IntStream.range(0, numSegments).boxed().forEach(x -> builder.add(newSegmentRecord(0, startingSegmentNumber + x, creationTime, x * keyRangeChunk, (x + 1) * keyRangeChunk)));
    EpochRecord epoch0 = new EpochRecord(0, 0, builder.build(), creationTime, 0L, 0L);
    return createEpochRecord(epoch0, context).thenCompose(r -> createHistoryChunk(epoch0, context)).thenCompose(r -> createSealedSegmentSizeMapShardIfAbsent(0, context)).thenCompose(r -> createRetentionSetDataIfAbsent(new RetentionSet(ImmutableList.of()), context)).thenCompose(r -> createCurrentEpochRecordDataIfAbsent(epoch0, context));
}
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) ImmutableList(com.google.common.collect.ImmutableList) RetentionSet(io.pravega.controller.store.stream.records.RetentionSet)

Example 5 with EpochRecord

use of io.pravega.controller.store.stream.records.EpochRecord in project pravega by pravega.

the class StreamMetadataTasks method checkScale.

/**
 * Helper method to check if scale operation against an epoch completed or not.
 *
 * @param scope          scope.
 * @param stream         stream name.
 * @param epoch          stream epoch.
 * @param requestId      request id.
 * @return returns the newly created segments.
 */
public CompletableFuture<ScaleStatusResponse> checkScale(String scope, String stream, int epoch, long requestId) {
    OperationContext context = streamMetadataStore.createStreamContext(scope, stream, requestId);
    CompletableFuture<EpochRecord> activeEpochFuture = streamMetadataStore.getActiveEpoch(scope, stream, context, true, executor);
    CompletableFuture<State> stateFuture = streamMetadataStore.getState(scope, stream, true, context, executor);
    CompletableFuture<EpochTransitionRecord> etrFuture = streamMetadataStore.getEpochTransition(scope, stream, context, executor).thenApply(VersionedMetadata::getObject);
    return CompletableFuture.allOf(stateFuture, activeEpochFuture, etrFuture).handle((r, ex) -> {
        ScaleStatusResponse.Builder response = ScaleStatusResponse.newBuilder();
        if (ex != null) {
            Throwable e = Exceptions.unwrap(ex);
            if (e instanceof StoreException.DataNotFoundException) {
                response.setStatus(ScaleStatusResponse.ScaleStatus.INVALID_INPUT);
            } else {
                response.setStatus(ScaleStatusResponse.ScaleStatus.INTERNAL_ERROR);
            }
        } else {
            EpochRecord activeEpoch = activeEpochFuture.join();
            State state = stateFuture.join();
            EpochTransitionRecord etr = etrFuture.join();
            if (epoch > activeEpoch.getEpoch()) {
                response.setStatus(ScaleStatusResponse.ScaleStatus.INVALID_INPUT);
            } else if (activeEpoch.getEpoch() == epoch || activeEpoch.getReferenceEpoch() == epoch) {
                response.setStatus(ScaleStatusResponse.ScaleStatus.IN_PROGRESS);
            } else {
                // has not completed.
                if (epoch + 1 == activeEpoch.getReferenceEpoch() && state.equals(State.SCALING) && (etr.equals(EpochTransitionRecord.EMPTY) || etr.getNewEpoch() == activeEpoch.getEpoch())) {
                    response.setStatus(ScaleStatusResponse.ScaleStatus.IN_PROGRESS);
                } else {
                    response.setStatus(ScaleStatusResponse.ScaleStatus.SUCCESS);
                }
            }
        }
        return response.build();
    });
}
Also used : OperationContext(io.pravega.controller.store.stream.OperationContext) EpochRecord(io.pravega.controller.store.stream.records.EpochRecord) EpochTransitionRecord(io.pravega.controller.store.stream.records.EpochTransitionRecord) ReaderGroupState(io.pravega.controller.store.stream.ReaderGroupState) State(io.pravega.controller.store.stream.State) ScaleStatusResponse(io.pravega.controller.stream.api.grpc.v1.Controller.ScaleStatusResponse) VersionedMetadata(io.pravega.controller.store.VersionedMetadata)

Aggregations

EpochRecord (io.pravega.controller.store.stream.records.EpochRecord)29 StreamConfiguration (io.pravega.client.stream.StreamConfiguration)21 UUID (java.util.UUID)21 Test (org.junit.Test)20 VersionedMetadata (io.pravega.controller.store.VersionedMetadata)19 EpochTransitionRecord (io.pravega.controller.store.stream.records.EpochTransitionRecord)19 ArrayList (java.util.ArrayList)19 StreamSegmentRecord (io.pravega.controller.store.stream.records.StreamSegmentRecord)18 Exceptions (io.pravega.common.Exceptions)17 Futures (io.pravega.common.concurrent.Futures)17 CommittingTransactionsRecord (io.pravega.controller.store.stream.records.CommittingTransactionsRecord)17 NameUtils.computeSegmentId (io.pravega.shared.NameUtils.computeSegmentId)17 HashMap (java.util.HashMap)17 List (java.util.List)17 Map (java.util.Map)17 Collectors (java.util.stream.Collectors)17 ImmutableMap (com.google.common.collect.ImmutableMap)16 Lists (com.google.common.collect.Lists)16 Version (io.pravega.controller.store.Version)16 StreamConfigurationRecord (io.pravega.controller.store.stream.records.StreamConfigurationRecord)16