Search in sources :

Example 36 with OperationContext

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

the class PravegaTablesKVTMetadataStore method recordLastKVTableSegment.

@Override
CompletableFuture<Void> recordLastKVTableSegment(final String scope, final String kvtable, int lastActiveSegment, OperationContext ctx, final Executor executor) {
    OperationContext context = getOperationContext(ctx);
    final String key = getScopedKVTName(scope, kvtable);
    return Futures.completeOn(storeHelper.createTable(DELETED_KVTABLES_TABLE, context.getRequestId()).thenCompose(created -> {
        return storeHelper.expectingDataNotFound(storeHelper.getCachedOrLoad(DELETED_KVTABLES_TABLE, key, BYTES_TO_INTEGER_FUNCTION, System.currentTimeMillis(), context.getRequestId()), null).thenCompose(existing -> {
            log.debug(context.getRequestId(), "Recording last segment {} for KeyValueTable {}/{} on deletion.", lastActiveSegment, scope, kvtable);
            if (existing != null) {
                final int oldLastActiveSegment = existing.getObject();
                Preconditions.checkArgument(lastActiveSegment >= oldLastActiveSegment, "Old last active segment ({}) for {}/{} is higher than current one {}.", oldLastActiveSegment, scope, kvtable, lastActiveSegment);
                return Futures.toVoid(storeHelper.updateEntry(DELETED_KVTABLES_TABLE, key, lastActiveSegment, INTEGER_TO_BYTES_FUNCTION, existing.getVersion(), context.getRequestId()));
            } else {
                return Futures.toVoid(storeHelper.addNewEntryIfAbsent(DELETED_KVTABLES_TABLE, key, lastActiveSegment, INTEGER_TO_BYTES_FUNCTION, context.getRequestId()));
            }
        });
    }), executor);
}
Also used : OperationContext(io.pravega.controller.store.stream.OperationContext) OperationContext(io.pravega.controller.store.stream.OperationContext) Getter(lombok.Getter) SegmentHelper(io.pravega.controller.server.SegmentHelper) Exceptions(io.pravega.common.Exceptions) LoggerFactory(org.slf4j.LoggerFactory) NameUtils.getQualifiedTableName(io.pravega.shared.NameUtils.getQualifiedTableName) CompletableFuture(java.util.concurrent.CompletableFuture) TagLogger(io.pravega.common.tracing.TagLogger) AccessLevel(lombok.AccessLevel) StoreException(io.pravega.controller.store.stream.StoreException) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) INTEGER_TO_BYTES_FUNCTION(io.pravega.controller.store.PravegaTablesStoreHelper.INTEGER_TO_BYTES_FUNCTION) NameUtils(io.pravega.shared.NameUtils) Executor(java.util.concurrent.Executor) CompletionException(java.util.concurrent.CompletionException) UUID(java.util.UUID) PravegaTablesScope(io.pravega.controller.store.PravegaTablesScope) CuratorFramework(org.apache.curator.framework.CuratorFramework) PravegaTablesStoreHelper(io.pravega.controller.store.PravegaTablesStoreHelper) BYTES_TO_INTEGER_FUNCTION(io.pravega.controller.store.PravegaTablesStoreHelper.BYTES_TO_INTEGER_FUNCTION) Preconditions(com.google.common.base.Preconditions) ZKHostIndex(io.pravega.controller.store.index.ZKHostIndex) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Futures(io.pravega.common.concurrent.Futures) GrpcAuthHelper(io.pravega.controller.server.security.auth.GrpcAuthHelper)

Example 37 with OperationContext

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

the class RequestHandlersTest method testDeleteScopeRecursive.

@Test
public void testDeleteScopeRecursive() {
    StreamMetadataStore streamStoreSpied = spy(getStore());
    KVTableMetadataStore kvtStoreSpied = spy(getKvtStore());
    OperationContext ctx = new OperationContext() {

        @Override
        public long getOperationStartTime() {
            return 0;
        }

        @Override
        public long getRequestId() {
            return 0;
        }
    };
    UUID scopeId = streamStoreSpied.getScopeId(scope, ctx, executor).join();
    doAnswer(x -> {
        CompletableFuture<UUID> cf = new CompletableFuture<>();
        cf.complete(scopeId);
        return cf;
    }).when(streamStoreSpied).getScopeId(eq(scope), eq(ctx), eq(executor));
    doAnswer(invocation -> {
        CompletableFuture<Boolean> cf = new CompletableFuture<>();
        cf.complete(false);
        return cf;
    }).when(streamStoreSpied).isScopeSealed(eq(scope), any(), any());
    DeleteScopeTask requestHandler = new DeleteScopeTask(streamMetadataTasks, streamStoreSpied, kvtStoreSpied, kvtTasks, executor);
    DeleteScopeEvent event = new DeleteScopeEvent(scope, System.currentTimeMillis(), scopeId);
    CompletableFuture<Void> future = CompletableFuture.completedFuture(null).thenComposeAsync(v -> requestHandler.execute(event), executor);
    future.join();
}
Also used : OperationContext(io.pravega.controller.store.stream.OperationContext) DeleteScopeTask(io.pravega.controller.server.eventProcessor.requesthandlers.DeleteScopeTask) CompletableFuture(java.util.concurrent.CompletableFuture) KVTableMetadataStore(io.pravega.controller.store.kvtable.KVTableMetadataStore) DeleteScopeEvent(io.pravega.shared.controller.event.DeleteScopeEvent) StreamMetadataStore(io.pravega.controller.store.stream.StreamMetadataStore) UUID(java.util.UUID) Test(org.junit.Test)

Example 38 with OperationContext

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

the class ControllerEventProcessorPravegaTablesStreamTest method testTxnPartialCommitRetry.

@Test(timeout = 10000)
public void testTxnPartialCommitRetry() {
    PravegaTablesStoreHelper storeHelper = spy(new PravegaTablesStoreHelper(SegmentHelperMock.getSegmentHelperMockForTables(executor), GrpcAuthHelper.getDisabledAuthHelper(), executor));
    this.streamStore = new PravegaTablesStreamMetadataStore(PRAVEGA_ZK_CURATOR_RESOURCE.client, executor, Duration.ofHours(Config.COMPLETED_TRANSACTION_TTL_IN_HOURS), storeHelper);
    SegmentHelper segmentHelperMock = SegmentHelperMock.getSegmentHelperMock();
    EventHelper eventHelperMock = EventHelperMock.getEventHelperMock(executor, "1", ((AbstractStreamMetadataStore) this.streamStore).getHostTaskIndex());
    StreamMetadataTasks streamMetadataTasks = new StreamMetadataTasks(streamStore, this.bucketStore, TaskStoreFactory.createInMemoryStore(executor), segmentHelperMock, executor, "1", GrpcAuthHelper.getDisabledAuthHelper(), eventHelperMock);
    StreamTransactionMetadataTasks streamTransactionMetadataTasks = new StreamTransactionMetadataTasks(this.streamStore, segmentHelperMock, executor, "host", GrpcAuthHelper.getDisabledAuthHelper());
    streamTransactionMetadataTasks.initializeStreamWriters(new EventStreamWriterMock<>(), new EventStreamWriterMock<>());
    String scope = "scope";
    String stream = "stream";
    // region createStream
    final ScalingPolicy policy1 = ScalingPolicy.fixed(2);
    final StreamConfiguration configuration1 = StreamConfiguration.builder().scalingPolicy(policy1).build();
    streamStore.createScope(scope, null, executor).join();
    long start = System.currentTimeMillis();
    streamStore.createStream(scope, stream, configuration1, start, null, executor).join();
    streamStore.setState(scope, stream, State.ACTIVE, null, executor).join();
    StreamMetadataTasks spyStreamMetadataTasks = spy(streamMetadataTasks);
    List<VersionedTransactionData> txnDataList = createAndCommitTransactions(3);
    int epoch = txnDataList.get(0).getEpoch();
    spyStreamMetadataTasks.setRequestEventWriter(new EventStreamWriterMock<>());
    CommitRequestHandler commitEventProcessor = new CommitRequestHandler(streamStore, spyStreamMetadataTasks, streamTransactionMetadataTasks, bucketStore, executor);
    final String committingTxnsRecordKey = "committingTxns";
    long failingClientRequestId = 123L;
    doReturn(failingClientRequestId).when(spyStreamMetadataTasks).getRequestId(any());
    OperationContext context = this.streamStore.createStreamContext(scope, stream, failingClientRequestId);
    streamStore.startCommitTransactions(scope, stream, 100, context, executor).join();
    doReturn(Futures.failedFuture(new RuntimeException())).when(storeHelper).updateEntry(anyString(), eq(committingTxnsRecordKey), any(), ArgumentMatchers.<Function<String, byte[]>>any(), any(), eq(failingClientRequestId));
    AssertExtensions.assertFutureThrows("Updating CommittingTxnRecord fails", commitEventProcessor.processEvent(new CommitEvent(scope, stream, epoch)), e -> Exceptions.unwrap(e) instanceof RuntimeException);
    verify(storeHelper, times(1)).removeEntries(anyString(), any(), eq(failingClientRequestId));
    VersionedMetadata<CommittingTransactionsRecord> versionedCommitRecord = this.streamStore.getVersionedCommittingTransactionsRecord(scope, stream, context, executor).join();
    CommittingTransactionsRecord commitRecord = versionedCommitRecord.getObject();
    assertFalse(CommittingTransactionsRecord.EMPTY.equals(commitRecord));
    for (VersionedTransactionData txnData : txnDataList) {
        checkTransactionState(scope, stream, txnData.getId(), TxnStatus.COMMITTED);
    }
    long goodClientRequestId = 4567L;
    doReturn(goodClientRequestId).when(spyStreamMetadataTasks).getRequestId(any());
    commitEventProcessor.processEvent(new CommitEvent(scope, stream, epoch)).join();
    versionedCommitRecord = this.streamStore.getVersionedCommittingTransactionsRecord(scope, stream, context, executor).join();
    commitRecord = versionedCommitRecord.getObject();
    assertTrue(CommittingTransactionsRecord.EMPTY.equals(commitRecord));
    for (VersionedTransactionData txnData : txnDataList) {
        checkTransactionState(scope, stream, txnData.getId(), TxnStatus.COMMITTED);
    }
}
Also used : OperationContext(io.pravega.controller.store.stream.OperationContext) ScalingPolicy(io.pravega.client.stream.ScalingPolicy) CommittingTransactionsRecord(io.pravega.controller.store.stream.records.CommittingTransactionsRecord) PravegaTablesStreamMetadataStore(io.pravega.controller.store.stream.PravegaTablesStreamMetadataStore) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) SegmentHelper(io.pravega.controller.server.SegmentHelper) VersionedTransactionData(io.pravega.controller.store.stream.VersionedTransactionData) CommitRequestHandler(io.pravega.controller.server.eventProcessor.requesthandlers.CommitRequestHandler) PravegaTablesStoreHelper(io.pravega.controller.store.PravegaTablesStoreHelper) StreamConfiguration(io.pravega.client.stream.StreamConfiguration) EventHelper(io.pravega.controller.task.EventHelper) StreamTransactionMetadataTasks(io.pravega.controller.task.Stream.StreamTransactionMetadataTasks) CommitEvent(io.pravega.shared.controller.event.CommitEvent) StreamMetadataTasks(io.pravega.controller.task.Stream.StreamMetadataTasks) Test(org.junit.Test)

Example 39 with OperationContext

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

the class MockStreamTransactionMetadataTasks method createTxn.

@Override
@Synchronized
public CompletableFuture<Pair<VersionedTransactionData, List<Segment>>> createTxn(final String scope, final String stream, final long lease, final long scaleGracePeriod, final OperationContext contextOpt) {
    final OperationContext context = contextOpt == null ? streamMetadataStore.createContext(scope, stream) : contextOpt;
    final UUID txnId = UUID.randomUUID();
    return streamMetadataStore.createTransaction(scope, stream, txnId, lease, 10 * lease, scaleGracePeriod, context, executor).thenCompose(txData -> {
        log.info("Created transaction {} with version {}", txData.getId(), txData.getVersion());
        return streamMetadataStore.getActiveSegments(scope, stream, context, executor).thenApply(segmentList -> new ImmutablePair<>(txData, segmentList));
    });
}
Also used : OperationContext(io.pravega.controller.store.stream.OperationContext) UUID(java.util.UUID) Synchronized(lombok.Synchronized)

Example 40 with OperationContext

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

the class StreamTransactionMetadataTasks method sealTxnBody.

/**
 * Seals a txn and transitions it to COMMITTING (resp. ABORTING) state if commit param is true (resp. false).
 *
 * Post-condition:
 * 1. If seal completes successfully, then
 *     (a) txn state is COMMITTING/ABORTING,
 *     (b) CommitEvent/AbortEvent is present in the commit stream/abort stream,
 *     (c) txn is removed from host-txn index,
 *     (d) txn is removed from the timeout service.
 *
 * 2. If process fails after transitioning txn to COMMITTING/ABORTING state, but before responding to client, then
 * since txn is present in the host-txn index, some other controller process shall put CommitEvent/AbortEvent to
 * commit stream/abort stream.
 *
 * @param host    host id. It is different from hostId iff invoked from TxnSweeper for aborting orphaned txn.
 * @param scope   scope name.
 * @param stream  stream name.
 * @param commit  boolean indicating whether to commit txn.
 * @param txnId   txn id.
 * @param version expected version of txn node in store.
 * @param ctx     context.
 * @return        Txn status after sealing it.
 */
CompletableFuture<TxnStatus> sealTxnBody(final String host, final String scope, final String stream, final boolean commit, final UUID txnId, final Integer version, final OperationContext ctx) {
    TxnResource resource = new TxnResource(scope, stream, txnId);
    Optional<Integer> versionOpt = Optional.ofNullable(version);
    // Step 1. Add txn to current host's index, if it is not already present
    CompletableFuture<Void> addIndex = host.equals(hostId) && !timeoutService.containsTxn(scope, stream, txnId) ? // then txn would no longer be open.
    streamMetadataStore.addTxnToIndex(hostId, resource, Integer.MAX_VALUE) : CompletableFuture.completedFuture(null);
    addIndex.whenComplete((v, e) -> {
        if (e != null) {
            log.debug("Txn={}, already present/newly added to host-txn index of host={}", txnId, hostId);
        } else {
            log.debug("Txn={}, added txn to host-txn index of host={}", txnId, hostId);
        }
    });
    // Step 2. Seal txn
    CompletableFuture<AbstractMap.SimpleEntry<TxnStatus, Integer>> sealFuture = addIndex.thenComposeAsync(x -> streamMetadataStore.sealTransaction(scope, stream, txnId, commit, versionOpt, ctx, executor), executor).whenComplete((v, e) -> {
        if (e != null) {
            log.debug("Txn={}, failed sealing txn", txnId);
        } else {
            log.debug("Txn={}, sealed successfully, commit={}", txnId, commit);
        }
    });
    // Step 3. write event to corresponding stream.
    return sealFuture.thenComposeAsync(pair -> {
        TxnStatus status = pair.getKey();
        switch(status) {
            case COMMITTING:
                return writeCommitEvent(scope, stream, pair.getValue(), txnId, status);
            case ABORTING:
                return writeAbortEvent(scope, stream, pair.getValue(), txnId, status);
            case ABORTED:
            case COMMITTED:
                return CompletableFuture.completedFuture(status);
            case OPEN:
            case UNKNOWN:
            default:
                // exception would be thrown.
                return CompletableFuture.completedFuture(status);
        }
    }, executor).thenComposeAsync(status -> {
        // Step 4. Remove txn from timeoutService, and from the index.
        timeoutService.removeTxn(scope, stream, txnId);
        log.debug("Txn={}, removed from timeout service", txnId);
        return streamMetadataStore.removeTxnFromIndex(host, resource, true).whenComplete((v, e) -> {
            if (e != null) {
                log.debug("Txn={}, failed removing txn from host-txn index of host={}", txnId, hostId);
            } else {
                log.debug("Txn={}, removed txn from host-txn index of host={}", txnId, hostId);
            }
        }).thenApply(x -> status);
    }, 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) TxnResource(io.pravega.controller.store.task.TxnResource) TxnStatus(io.pravega.controller.store.stream.TxnStatus) PingTxnStatus(io.pravega.controller.stream.api.grpc.v1.Controller.PingTxnStatus)

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