Search in sources :

Example 1 with OperationContext

use of io.pravega.controller.store.stream.OperationContext in project pravega by pravega.

the class CommitEventProcessor method process.

@Override
protected void process(CommitEvent event, Position position) {
    String scope = event.getScope();
    String stream = event.getStream();
    int epoch = event.getEpoch();
    UUID txnId = event.getTxid();
    OperationContext context = streamMetadataStore.createContext(scope, stream);
    log.debug("Committing transaction {} on stream {}/{}", event.getTxid(), event.getScope(), event.getStream());
    streamMetadataStore.getActiveEpoch(scope, stream, context, false, executor).thenComposeAsync(pair -> {
        // complete before transitioning the stream to new epoch.
        if (epoch < pair.getKey()) {
            return CompletableFuture.completedFuture(null);
        } else if (epoch == pair.getKey()) {
            // If the transaction's epoch is same as the stream's current epoch, commit it.
            return completeCommit(scope, stream, epoch, txnId, context, this.streamMetadataTasks.retrieveDelegationToken());
        } else {
            // Otherwise, postpone commit operation until the stream transitions to next epoch.
            return postponeCommitEvent(event);
        }
    }).whenCompleteAsync((result, error) -> {
        if (error != null) {
            log.error("Failed committing transaction {} on stream {}/{}", txnId, scope, stream);
        } else {
            log.debug("Successfully committed transaction {} on stream {}/{}", txnId, scope, stream);
            if (processedEvents != null) {
                processedEvents.offer(event);
            }
        }
    }, executor).join();
}
Also used : OperationContext(io.pravega.controller.store.stream.OperationContext) CommitEvent(io.pravega.shared.controller.event.CommitEvent) OperationContext(io.pravega.controller.store.stream.OperationContext) Retry(io.pravega.common.util.Retry) SegmentHelper(io.pravega.controller.server.SegmentHelper) EventProcessor(io.pravega.controller.eventProcessor.impl.EventProcessor) Exceptions(io.pravega.common.Exceptions) BlockingQueue(java.util.concurrent.BlockingQueue) CompletableFuture(java.util.concurrent.CompletableFuture) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) WriteFailedException(io.pravega.controller.task.Stream.WriteFailedException) Position(io.pravega.client.stream.Position) HostControllerStore(io.pravega.controller.store.host.HostControllerStore) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) StreamMetadataTasks(io.pravega.controller.task.Stream.StreamMetadataTasks) VisibleForTesting(com.google.common.annotations.VisibleForTesting) ConnectionFactory(io.pravega.client.netty.impl.ConnectionFactory) Controller(io.pravega.controller.stream.api.grpc.v1.Controller) StreamMetadataStore(io.pravega.controller.store.stream.StreamMetadataStore) Futures(io.pravega.common.concurrent.Futures) UUID(java.util.UUID)

Example 2 with OperationContext

use of io.pravega.controller.store.stream.OperationContext in project pravega by pravega.

the class StreamMetadataTasks method sealStream.

/**
 * Seal a stream.
 *
 * @param scope      scope.
 * @param stream     stream name.
 * @param contextOpt optional context
 * @return update status.
 */
public CompletableFuture<UpdateStreamStatus.Status> sealStream(String scope, String stream, OperationContext contextOpt) {
    final OperationContext context = contextOpt == null ? streamMetadataStore.createContext(scope, stream) : contextOpt;
    // 1. post event for seal.
    SealStreamEvent event = new SealStreamEvent(scope, stream);
    return writeEvent(event).thenCompose(x -> streamMetadataStore.getState(scope, stream, false, context, executor)).thenCompose(state -> {
        if (state.equals(State.SEALED)) {
            return CompletableFuture.completedFuture(true);
        } else {
            return streamMetadataStore.setState(scope, stream, State.SEALING, context, executor);
        }
    }).thenCompose(result -> {
        if (result) {
            return checkDone(() -> isSealed(scope, stream, context)).thenApply(x -> UpdateStreamStatus.Status.SUCCESS);
        } else {
            return CompletableFuture.completedFuture(UpdateStreamStatus.Status.FAILURE);
        }
    }).exceptionally(ex -> {
        log.warn("Exception thrown in trying to notify sealed segments {}", ex.getMessage());
        return handleUpdateStreamError(ex);
    });
}
Also used : OperationContext(io.pravega.controller.store.stream.OperationContext) UpdateStreamEvent(io.pravega.shared.controller.event.UpdateStreamEvent) ControllerEventProcessors(io.pravega.controller.server.eventProcessor.ControllerEventProcessors) EventStreamWriter(io.pravega.client.stream.EventStreamWriter) StreamConfiguration(io.pravega.client.stream.StreamConfiguration) SealStreamEvent(io.pravega.shared.controller.event.SealStreamEvent) StoreException(io.pravega.controller.store.stream.StoreException) TaskMetadataStore(io.pravega.controller.store.task.TaskMetadataStore) TaskStepsRetryHelper.withRetries(io.pravega.controller.task.Stream.TaskStepsRetryHelper.withRetries) Duration(java.time.Duration) Map(java.util.Map) TaskExceptions(io.pravega.controller.server.eventProcessor.requesthandlers.TaskExceptions) CreateStreamStatus(io.pravega.controller.stream.api.grpc.v1.Controller.CreateStreamStatus) ScaleOperationExceptions(io.pravega.controller.store.stream.ScaleOperationExceptions) ImmutableMap(com.google.common.collect.ImmutableMap) DeleteStreamEvent(io.pravega.shared.controller.event.DeleteStreamEvent) CompletionException(java.util.concurrent.CompletionException) State(io.pravega.controller.store.stream.tables.State) Collectors(java.util.stream.Collectors) ControllerEvent(io.pravega.shared.controller.event.ControllerEvent) Serializable(java.io.Serializable) MetricsProvider(io.pravega.shared.metrics.MetricsProvider) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) CompletionStage(java.util.concurrent.CompletionStage) Config(io.pravega.controller.util.Config) ClientFactory(io.pravega.client.ClientFactory) Optional(java.util.Optional) Resource(io.pravega.controller.store.task.Resource) StreamMetadataStore(io.pravega.controller.store.stream.StreamMetadataStore) Futures(io.pravega.common.concurrent.Futures) IntStream(java.util.stream.IntStream) NotImplementedException(org.apache.commons.lang3.NotImplementedException) OperationContext(io.pravega.controller.store.stream.OperationContext) SegmentHelper(io.pravega.controller.server.SegmentHelper) RetentionPolicy(io.pravega.client.stream.RetentionPolicy) Exceptions(io.pravega.common.Exceptions) PravegaInterceptor(io.pravega.controller.server.rpc.auth.PravegaInterceptor) TruncateStreamEvent(io.pravega.shared.controller.event.TruncateStreamEvent) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ScaleStatusResponse(io.pravega.controller.stream.api.grpc.v1.Controller.ScaleStatusResponse) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) Supplier(java.util.function.Supplier) StreamCutRecord(io.pravega.controller.store.stream.StreamCutRecord) DynamicLogger(io.pravega.shared.metrics.DynamicLogger) DeleteStreamStatus(io.pravega.controller.stream.api.grpc.v1.Controller.DeleteStreamStatus) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) Segment(io.pravega.controller.store.stream.Segment) ConnectionFactory(io.pravega.client.netty.impl.ConnectionFactory) ModelHelper(io.pravega.client.stream.impl.ModelHelper) ScaleResponse(io.pravega.controller.stream.api.grpc.v1.Controller.ScaleResponse) EventWriterConfig(io.pravega.client.stream.EventWriterConfig) Task(io.pravega.controller.task.Task) TaskBase(io.pravega.controller.task.TaskBase) MetricsNames.nameFromStream(io.pravega.shared.MetricsNames.nameFromStream) CreateStreamResponse(io.pravega.controller.store.stream.CreateStreamResponse) WireCommands(io.pravega.shared.protocol.netty.WireCommands) SegmentRange(io.pravega.controller.stream.api.grpc.v1.Controller.SegmentRange) AbstractMap(java.util.AbstractMap) UpdateStreamStatus(io.pravega.controller.stream.api.grpc.v1.Controller.UpdateStreamStatus) RETENTION_FREQUENCY(io.pravega.shared.MetricsNames.RETENTION_FREQUENCY) HostControllerStore(io.pravega.controller.store.host.HostControllerStore) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Comparator(java.util.Comparator) ScaleOpEvent(io.pravega.shared.controller.event.ScaleOpEvent) ScalingPolicy(io.pravega.client.stream.ScalingPolicy) SealStreamEvent(io.pravega.shared.controller.event.SealStreamEvent)

Example 3 with OperationContext

use of io.pravega.controller.store.stream.OperationContext in project pravega by pravega.

the class StreamTransactionMetadataTasks method createTxnBody.

/**
 * Creates txn on the specified stream.
 *
 * Post-condition:
 * 1. If txn creation succeeds, then
 *     (a) txn node is created in the store,
 *     (b) txn segments are successfully created on respective segment stores,
 *     (c) txn is present in the host-txn index of current host,
 *     (d) txn's timeout is being tracked in timeout service.
 *
 * 2. If process fails after creating txn node, but before responding to the client, then since txn is
 * present in the host-txn index, some other controller process shall abort the txn after maxLeaseValue
 *
 * 3. If timeout service tracks timeout of specified txn,
 * then txn is also present in the host-txn index of current process.
 *
 * Invariant:
 * The following invariants are maintained throughout the execution of createTxn, pingTxn and sealTxn methods.
 * 1. If timeout service tracks timeout of a txn, then txn is also present in the host-txn index of current process.
 * 2. If txn znode is updated, then txn is also present in the host-txn index of current process.
 *
 * @param scope               scope name.
 * @param stream              stream name.
 * @param lease               txn lease.
 * @param scaleGracePeriod    amount of time for which txn may remain open after scale operation is initiated.
 * @param ctx                 context.
 * @return                    identifier of the created txn.
 */
CompletableFuture<Pair<VersionedTransactionData, List<Segment>>> createTxnBody(final String scope, final String stream, final long lease, final long scaleGracePeriod, final OperationContext ctx) {
    // Step 1. Validate parameters.
    CompletableFuture<Void> validate = validate(lease, scaleGracePeriod);
    long maxExecutionPeriod = Math.min(MAX_EXECUTION_TIME_MULTIPLIER * lease, Duration.ofDays(1).toMillis());
    UUID txnId = UUID.randomUUID();
    TxnResource resource = new TxnResource(scope, stream, txnId);
    // Step 2. Add txn to host-transaction index.
    CompletableFuture<Void> addIndex = validate.thenComposeAsync(ignore -> streamMetadataStore.addTxnToIndex(hostId, resource, 0), executor).whenComplete((v, e) -> {
        if (e != null) {
            log.debug("Txn={}, failed adding txn to host-txn index of host={}", txnId, hostId);
        } else {
            log.debug("Txn={}, added txn to host-txn index of host={}", txnId, hostId);
        }
    });
    // Step 3. Create txn node in the store.
    CompletableFuture<VersionedTransactionData> txnFuture = addIndex.thenComposeAsync(ignore -> streamMetadataStore.createTransaction(scope, stream, txnId, lease, maxExecutionPeriod, scaleGracePeriod, ctx, executor), executor).whenComplete((v, e) -> {
        if (e != null) {
            log.debug("Txn={}, failed creating txn in store", txnId);
        } else {
            log.debug("Txn={}, created in store", txnId);
        }
    });
    // Step 4. Notify segment stores about new txn.
    CompletableFuture<List<Segment>> segmentsFuture = txnFuture.thenComposeAsync(txnData -> streamMetadataStore.getActiveSegments(scope, stream, txnData.getEpoch(), ctx, executor), executor);
    CompletableFuture<Void> notify = segmentsFuture.thenComposeAsync(activeSegments -> notifyTxnCreation(scope, stream, activeSegments, txnId), executor).whenComplete((v, e) -> log.debug("Txn={}, notified segments stores", txnId));
    // Step 5. Start tracking txn in timeout service
    return notify.whenCompleteAsync((result, ex) -> {
        int version = 0;
        long executionExpiryTime = System.currentTimeMillis() + maxExecutionPeriod;
        if (!txnFuture.isCompletedExceptionally()) {
            version = txnFuture.join().getVersion();
            executionExpiryTime = txnFuture.join().getMaxExecutionExpiryTime();
        }
        timeoutService.addTxn(scope, stream, txnId, version, lease, executionExpiryTime, scaleGracePeriod);
        log.debug("Txn={}, added to timeout service on host={}", txnId, hostId);
    }, executor).thenApplyAsync(v -> new ImmutablePair<>(txnFuture.join(), segmentsFuture.join()), executor);
}
Also used : CommitEvent(io.pravega.shared.controller.event.CommitEvent) OperationContext(io.pravega.controller.store.stream.OperationContext) ControllerEventProcessors(io.pravega.controller.server.eventProcessor.ControllerEventProcessors) Getter(lombok.Getter) EventStreamWriter(io.pravega.client.stream.EventStreamWriter) SegmentHelper(io.pravega.controller.server.SegmentHelper) PravegaInterceptor(io.pravega.controller.server.rpc.auth.PravegaInterceptor) CompletableFuture(java.util.concurrent.CompletableFuture) TimeoutServiceConfig(io.pravega.controller.timeout.TimeoutServiceConfig) Status(io.pravega.controller.stream.api.grpc.v1.Controller.PingTxnStatus.Status) AbortEvent(io.pravega.shared.controller.event.AbortEvent) Pair(org.apache.commons.lang3.tuple.Pair) Duration(java.time.Duration) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) RETRYABLE_PREDICATE(io.pravega.controller.util.RetryHelper.RETRYABLE_PREDICATE) Segment(io.pravega.controller.store.stream.Segment) TimerWheelTimeoutService(io.pravega.controller.timeout.TimerWheelTimeoutService) ConnectionFactory(io.pravega.client.netty.impl.ConnectionFactory) EventWriterConfig(io.pravega.client.stream.EventWriterConfig) RetryHelper.withRetriesAsync(io.pravega.controller.util.RetryHelper.withRetriesAsync) ControllerEventProcessorConfig(io.pravega.controller.server.eventProcessor.ControllerEventProcessorConfig) BlockingQueue(java.util.concurrent.BlockingQueue) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) TxnResource(io.pravega.controller.store.task.TxnResource) ImmutablePair(org.apache.commons.lang3.tuple.ImmutablePair) TimeUnit(java.util.concurrent.TimeUnit) CountDownLatch(java.util.concurrent.CountDownLatch) AbstractMap(java.util.AbstractMap) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) Config(io.pravega.controller.util.Config) HostControllerStore(io.pravega.controller.store.host.HostControllerStore) TxnStatus(io.pravega.controller.store.stream.TxnStatus) ClientFactory(io.pravega.client.ClientFactory) VersionedTransactionData(io.pravega.controller.store.stream.VersionedTransactionData) Optional(java.util.Optional) TimeoutService(io.pravega.controller.timeout.TimeoutService) VisibleForTesting(com.google.common.annotations.VisibleForTesting) StreamMetadataStore(io.pravega.controller.store.stream.StreamMetadataStore) PingTxnStatus(io.pravega.controller.stream.api.grpc.v1.Controller.PingTxnStatus) Futures(io.pravega.common.concurrent.Futures) List(java.util.List) UUID(java.util.UUID) VersionedTransactionData(io.pravega.controller.store.stream.VersionedTransactionData) TxnResource(io.pravega.controller.store.task.TxnResource)

Example 4 with OperationContext

use of io.pravega.controller.store.stream.OperationContext in project pravega by pravega.

the class ControllerService method checkTransactionStatus.

/**
 * Checks transaction status.
 * @param scope scope
 * @param stream stream name
 * @param txnId transaction id
 * @param requestId request id
 * @return Transaction state future
 */
public CompletableFuture<TxnState> checkTransactionStatus(final String scope, final String stream, final UUID txnId, final long requestId) {
    Exceptions.checkNotNullOrEmpty(scope, "scope");
    Exceptions.checkNotNullOrEmpty(stream, "stream");
    Preconditions.checkNotNull(txnId, "txnId");
    OperationContext context = streamStore.createStreamContext(scope, stream, requestId);
    return streamStore.transactionStatus(scope, stream, txnId, context, executor).thenApplyAsync(res -> TxnState.newBuilder().setState(TxnState.State.valueOf(res.name())).build(), executor);
}
Also used : OperationContext(io.pravega.controller.store.stream.OperationContext)

Example 5 with OperationContext

use of io.pravega.controller.store.stream.OperationContext in project pravega by pravega.

the class ControllerService method getSegmentsImmediatelyFollowing.

public CompletableFuture<Map<SegmentRange, List<Long>>> getSegmentsImmediatelyFollowing(SegmentId segment, long requestId) {
    Preconditions.checkNotNull(segment, "segment");
    String scope = segment.getStreamInfo().getScope();
    String stream = segment.getStreamInfo().getStream();
    OperationContext context = streamStore.createStreamContext(scope, stream, requestId);
    return streamStore.getSuccessors(scope, stream, segment.getSegmentId(), context, executor).thenApply(successors -> successors.entrySet().stream().collect(Collectors.toMap(entry -> ModelHelper.createSegmentRange(scope, stream, entry.getKey().segmentId(), entry.getKey().getKeyStart(), entry.getKey().getKeyEnd()), Map.Entry::getValue)));
}
Also used : OperationContext(io.pravega.controller.store.stream.OperationContext)

Aggregations

OperationContext (io.pravega.controller.store.stream.OperationContext)76 CompletableFuture (java.util.concurrent.CompletableFuture)53 Futures (io.pravega.common.concurrent.Futures)48 StreamMetadataStore (io.pravega.controller.store.stream.StreamMetadataStore)44 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)42 Exceptions (io.pravega.common.Exceptions)41 Collectors (java.util.stream.Collectors)41 UUID (java.util.UUID)39 StoreException (io.pravega.controller.store.stream.StoreException)38 List (java.util.List)38 TagLogger (io.pravega.common.tracing.TagLogger)37 LoggerFactory (org.slf4j.LoggerFactory)37 Preconditions (com.google.common.base.Preconditions)36 Map (java.util.Map)32 NameUtils (io.pravega.shared.NameUtils)31 VisibleForTesting (com.google.common.annotations.VisibleForTesting)27 StreamConfiguration (io.pravega.client.stream.StreamConfiguration)26 State (io.pravega.controller.store.stream.State)26 CompletionException (java.util.concurrent.CompletionException)26 BucketStore (io.pravega.controller.store.stream.BucketStore)25