Search in sources :

Example 1 with CommittingTransactionsRecord

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

the class ControllerMetadataJsonSerializerTest method testCommittingTransactionsRecord.

@Test
public void testCommittingTransactionsRecord() {
    List<UUID> list = Lists.newArrayList(UUID.randomUUID(), UUID.randomUUID());
    CommittingTransactionsRecord record0 = new CommittingTransactionsRecord(0, ImmutableList.copyOf(list));
    testRecordSerialization(record0, CommittingTransactionsRecord.class);
    CommittingTransactionsRecord record = record0.createRollingTxnRecord(10);
    testRecordSerialization(record, CommittingTransactionsRecord.class);
}
Also used : CommittingTransactionsRecord(io.pravega.controller.store.stream.records.CommittingTransactionsRecord) UUID(java.util.UUID) Test(org.junit.Test)

Example 2 with CommittingTransactionsRecord

use of io.pravega.controller.store.stream.records.CommittingTransactionsRecord 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 3 with CommittingTransactionsRecord

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

the class PersistentStreamBase method completeCommittingTransactions.

@Override
public CompletableFuture<Void> completeCommittingTransactions(VersionedMetadata<CommittingTransactionsRecord> record, OperationContext context, Map<String, TxnWriterMark> writerMarks) {
    Preconditions.checkNotNull(context, "operation context cannot be null");
    // Chain all transaction commit futures one after the other. This will ensure that order of commit
    // if honoured and is based on the order in the list.
    CompletableFuture<Void> future = generateMarksForTransactions(context, writerMarks);
    for (UUID txnId : record.getObject().getTransactionsToCommit()) {
        log.debug(context.getRequestId(), "Committing transaction {} on stream {}/{}", txnId, scope, name);
        // commit transaction in segment store
        future = future.thenCompose(x -> commitTransaction(txnId, context).thenAccept(done -> {
            log.debug(context.getRequestId(), "transaction {} on stream {}/{} committed successfully", txnId, scope, name);
        }));
    }
    return future.thenCompose(x -> Futures.toVoid(updateCommittingTxnRecord(new VersionedMetadata<>(CommittingTransactionsRecord.EMPTY, record.getVersion()), 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) UUID(java.util.UUID)

Example 4 with CommittingTransactionsRecord

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

the class PersistentStreamBase method completeRollingTxn.

@Override
public CompletableFuture<Void> completeRollingTxn(Map<Long, Long> sealedActiveEpochSegments, VersionedMetadata<CommittingTransactionsRecord> versionedMetadata, OperationContext context) {
    Preconditions.checkNotNull(context, "Operation context cannot be null");
    return getActiveEpoch(true, context).thenCompose(activeEpochRecord -> {
        CommittingTransactionsRecord committingTxnRecord = versionedMetadata.getObject();
        int activeEpoch = committingTxnRecord.getCurrentEpoch();
        if (activeEpochRecord.getEpoch() == activeEpoch) {
            return updateSealedSegmentSizes(sealedActiveEpochSegments, context).thenCompose(x -> clearMarkers(sealedActiveEpochSegments.keySet(), context)).thenCompose(x -> updateCurrentEpochRecord(committingTxnRecord.getNewActiveEpoch(), context));
        } else {
            return CompletableFuture.completedFuture(null);
        }
    });
}
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) CommittingTransactionsRecord(io.pravega.controller.store.stream.records.CommittingTransactionsRecord)

Example 5 with CommittingTransactionsRecord

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

the class PersistentStreamBase method startRollingTxn.

@Override
public CompletableFuture<VersionedMetadata<CommittingTransactionsRecord>> startRollingTxn(int activeEpoch, VersionedMetadata<CommittingTransactionsRecord> existing, OperationContext context) {
    Preconditions.checkNotNull(context, "Operation context cannot be null");
    CommittingTransactionsRecord record = existing.getObject();
    if (record.isRollingTxnRecord()) {
        return CompletableFuture.completedFuture(existing);
    } else {
        CommittingTransactionsRecord update = record.createRollingTxnRecord(activeEpoch);
        return updateCommittingTxnRecord(new VersionedMetadata<>(update, existing.getVersion()), context).thenApply(version -> new VersionedMetadata<>(update, version));
    }
}
Also used : CommittingTransactionsRecord(io.pravega.controller.store.stream.records.CommittingTransactionsRecord) VersionedMetadata(io.pravega.controller.store.VersionedMetadata)

Aggregations

CommittingTransactionsRecord (io.pravega.controller.store.stream.records.CommittingTransactionsRecord)17 UUID (java.util.UUID)14 StreamConfiguration (io.pravega.client.stream.StreamConfiguration)12 VersionedMetadata (io.pravega.controller.store.VersionedMetadata)11 EpochRecord (io.pravega.controller.store.stream.records.EpochRecord)11 CompletableFuture (java.util.concurrent.CompletableFuture)11 ImmutableMap (com.google.common.collect.ImmutableMap)10 Exceptions (io.pravega.common.Exceptions)10 Futures (io.pravega.common.concurrent.Futures)10 NameUtils.computeSegmentId (io.pravega.shared.NameUtils.computeSegmentId)10 ArrayList (java.util.ArrayList)10 HashMap (java.util.HashMap)10 List (java.util.List)10 Map (java.util.Map)10 Collectors (java.util.stream.Collectors)10 EpochTransitionRecord (io.pravega.controller.store.stream.records.EpochTransitionRecord)9 StreamTruncationRecord (io.pravega.controller.store.stream.records.StreamTruncationRecord)9 WriterMark (io.pravega.controller.store.stream.records.WriterMark)9 Lists (com.google.common.collect.Lists)8 ScalingPolicy (io.pravega.client.stream.ScalingPolicy)8