Ejemplo n.º 1
0
    /// <inheritdoc/>
    public override async Task Connect(
        IAsyncStreamReader <FilterClientToRuntimeMessage> runtimeStream,
        IServerStreamWriter <FilterRuntimeToClientMessage> clientStream,
        ServerCallContext context)
    {
        _logger.FilterConnectionRequestedFor("Unpartitioned");
        using var cts = CancellationTokenSource.CreateLinkedTokenSource(_hostApplicationLifetime.ApplicationStopping, context.CancellationToken);
        var tryConnect = await _reverseCallServices.Connect(
            runtimeStream,
            clientStream,
            context,
            _unpartitionedFiltersProtocol,
            cts.Token).ConfigureAwait(false);

        if (!tryConnect.Success)
        {
            return;
        }
        using var dispatcher = tryConnect.Result.dispatcher;
        var arguments = tryConnect.Result.arguments;
        var createExecutionContext = await CreateExecutionContextOrReject(dispatcher, arguments.ExecutionContext, cts.Token).ConfigureAwait(false);

        if (!createExecutionContext.Success)
        {
            return;
        }

        var executionContext = createExecutionContext.Result;

        if (await RejectIfInvalidFilterId(dispatcher, arguments.Filter, cts.Token).ConfigureAwait(false))
        {
            return;
        }

        var filterDefinition = new FilterDefinition(StreamId.EventLog, arguments.Filter.Value, false);

        await RegisterFilter(
            dispatcher,
            arguments.Scope,
            filterDefinition,
            tenant => _createUnpartitionedFilterProcessorFor(
                tenant,
                arguments.Scope,
                filterDefinition,
                dispatcher),
            executionContext,
            cts.Token).ConfigureAwait(false);
    }
Ejemplo n.º 2
0
    /// <inheritdoc/>
    public override async Task Connect(
        IAsyncStreamReader <EventHandlerClientToRuntimeMessage> runtimeStream,
        IServerStreamWriter <EventHandlerRuntimeToClientMessage> clientStream,
        ServerCallContext context)
    {
        _logger.ConnectingEventHandler();
        using var cts = CancellationTokenSource.CreateLinkedTokenSource(_hostApplicationLifetime.ApplicationStopping, context.CancellationToken);
        try
        {
            var connectResult = await _reverseCallServices.Connect(runtimeStream, clientStream, context, _eventHandlersProtocol, cts.Token).ConfigureAwait(false);

            if (!connectResult.Success)
            {
                return;
            }

            using var dispatcher = connectResult.Result.dispatcher;
            var arguments = connectResult.Result.arguments;
            using var eventHandler = _configuration.Value.Fast
                ? _eventHandlerFactory.CreateFast(arguments, _configuration.Value.ImplicitFilter, dispatcher, context.CancellationToken)
                : _eventHandlerFactory.Create(arguments, dispatcher, context.CancellationToken);

            await _eventHandlers.RegisterAndStart(
                eventHandler,
                (failure, cancellation) => dispatcher.Reject(new EventHandlerRegistrationResponse {
                Failure = failure.ToProtobuf()
            }, cancellation),
                cts.Token).ConfigureAwait(false);
        }
        finally
        {
            cts.Cancel();
        }
    }
Ejemplo n.º 3
0
    /// <inheritdoc/>
    public override async Task Subscribe(
        IAsyncStreamReader <EventHorizonConsumerToProducerMessage> producerStream,
        IServerStreamWriter <EventHorizonProducerToConsumerMessage> consumerStream,
        ServerCallContext context)
    {
        Log.IncomingEventHorizonSubscription(_logger);
        var connectResult = await _reverseCalls.Connect(
            producerStream,
            consumerStream,
            context,
            _protocol,
            context.CancellationToken,
            true).ConfigureAwait(false);

        if (!connectResult.Success)
        {
            return;
        }

        using var dispatcher = connectResult.Result.dispatcher;
        var arguments = connectResult.Result.arguments;

        _metrics.IncrementTotalIncomingSubscriptions();
        Log.IncomingEventHorizonSubscriptionWithArguments(
            _logger,
            arguments.ConsumerMicroservice,
            arguments.ConsumerTenant,
            arguments.ProducerTenant,
            arguments.StreamPosition,
            arguments.Partition,
            arguments.PublicStream);

        if (!TryGetConsent(arguments, out var consent, out var failureResponse))
        {
            _metrics.IncrementTotalRejectedSubscriptions();
            await dispatcher.Reject(failureResponse, context.CancellationToken).ConfigureAwait(false);

            return;
        }

        _metrics.IncrementTotalAcceptedSubscriptions();
        Log.SuccessfullySubscribed(
            _logger,
            arguments.ConsumerMicroservice,
            arguments.ConsumerTenant,
            arguments.ProducerTenant,
            arguments.StreamPosition,
            arguments.Partition,
            arguments.PublicStream);
        await _eventHorizons.Start(dispatcher, arguments, consent, context.CancellationToken).ConfigureAwait(false);
    }
Ejemplo n.º 4
0
    /// <inheritdoc/>
    public override async Task Connect(
        IAsyncStreamReader <ProjectionClientToRuntimeMessage> runtimeStream,
        IServerStreamWriter <ProjectionRuntimeToClientMessage> clientStream,
        ServerCallContext context)
    {
        // TODO: It seems like things are not properly unregistered on exceptions?
        // TODO: I tested this out and while making the DI container work, it kept failing and telling me that the projection was already registered on the second attempt.

        Log.ConnectingProjections(_logger);
        using var cts = CancellationTokenSource.CreateLinkedTokenSource(_hostApplicationLifetime.ApplicationStopping, context.CancellationToken);
        var tryConnect = await _reverseCallServices.Connect(runtimeStream, clientStream, context, _protocol, cts.Token).ConfigureAwait(false);

        if (!tryConnect.Success)
        {
            return;
        }
        using var dispatcher = tryConnect.Result.dispatcher;
        var arguments        = tryConnect.Result.arguments;
        var executionContext = arguments.ExecutionContext;
        var definition       = arguments.ProjectionDefinition;

        var tryCreateExecutionContext = _executionContextCreator.TryCreateUsing(arguments.ExecutionContext);

        if (!tryCreateExecutionContext.Success)
        {
            await dispatcher.Reject(
                _protocol.CreateFailedConnectResponse($"Failed to register Projection because the execution context is invalid: ${tryCreateExecutionContext.Exception.Message}"),
                cts.Token).ConfigureAwait(false);

            return;
        }

        Log.ReceivedProjectionArguments(_logger, definition.Scope, definition.Projection);

        var projection   = new Projection(dispatcher, definition, arguments.Alias, arguments.HasAlias);
        var registration = await _projections.Register(projection, executionContext, cts.Token);

        if (!registration.Success)
        {
            Log.ErrorWhileRegisteringProjection(_logger, definition.Scope, definition.Projection, registration.Exception);
            await dispatcher.Reject(new ProjectionRegistrationResponse
            {
                Failure = new Failure(
                    ProjectionFailures.FailedToRegisterProjection,
                    $"Failed to register Projection {projection.Definition.Projection}. {registration.Exception.Message}")
            }, cts.Token).ConfigureAwait(false);

            return;
        }

        using var processor = registration.Result;
        var reverseCall = dispatcher.Accept(new ProjectionRegistrationResponse(), cts.Token);
        var processing  = processor.Start();

        var tasks = new TaskGroup(reverseCall, processing);

        tasks.OnFirstTaskFailure  += (_, ex) => Log.ErrorWhileRunningProjection(_logger, projection.Definition.Scope, projection.Definition.Projection, ex);
        tasks.OnAllTasksCompleted += () => Log.ProjectionDisconnected(_logger, projection.Definition.Scope, projection.Definition.Projection);

        await tasks.WaitForAllCancellingOnFirst(cts).ConfigureAwait(false);
    }
Ejemplo n.º 5
0
    /// <inheritdoc/>
    public override async Task Connect(
        IAsyncStreamReader <EmbeddingClientToRuntimeMessage> runtimeStream,
        IServerStreamWriter <EmbeddingRuntimeToClientMessage> clientStream,
        ServerCallContext context)
    {
        // TODO: It seems like things are not properly unregistered on exceptions?
        // TODO: I tested this out and while making the DI container work, it kept failing and telling me that the projection was already registered on the second attempt.

        Log.ConnectingEmbeddings(_logger);
        using var cts = CancellationTokenSource.CreateLinkedTokenSource(_hostApplicationLifetime.ApplicationStopping, context.CancellationToken);
        var connection = await _reverseCallServices.Connect(runtimeStream, clientStream, context, _protocol, context.CancellationToken).ConfigureAwait(false);

        if (!connection.Success)
        {
            return;
        }
        using var dispatcher = connection.Result.dispatcher;
        var arguments = connection.Result.arguments;

        var tryCreateExecutionContext = _executionContextCreator.TryCreateUsing(arguments.ExecutionContext);

        if (!tryCreateExecutionContext.Success)
        {
            await dispatcher.Reject(
                _protocol.CreateFailedConnectResponse($"Failed to register embedding because the execution context is invalid: ${tryCreateExecutionContext.Exception.Message}"),
                cts.Token).ConfigureAwait(false);

            return;
        }

        var executionContext = tryCreateExecutionContext.Result; // TODO: Use this

        if (_embeddingProcessors.HasEmbeddingProcessors(arguments.Definition.Embedding))
        {
            await dispatcher.Reject(
                _protocol.CreateFailedConnectResponse($"Failed to register Embedding: {arguments.Definition.Embedding.Value}. Embedding already registered with the same id"),
                cts.Token).ConfigureAwait(false);

            return;
        }

        if (await RejectIfInvalidDefinition(arguments.Definition, dispatcher, cts.Token).ConfigureAwait(false))
        {
            return;
        }
        var persistDefinition = await _embeddingDefinitionPersister.TryPersist(arguments.Definition, cts.Token).ConfigureAwait(false);

        if (!persistDefinition.Success)
        {
            await dispatcher.Reject(
                _protocol.CreateFailedConnectResponse($"Failed to register Embedding: {arguments.Definition.Embedding.Value}. Failed to persist embedding definition. {persistDefinition.Exception.Message}"),
                cts.Token).ConfigureAwait(false);

            return;
        }

        var dispatcherTask = dispatcher.Accept(new EmbeddingRegistrationResponse(), cts.Token);
        var processorTask  = _embeddingProcessors.TryStartEmbeddingProcessorForAllTenants(
            arguments.Definition.Embedding,
            tenant => _getEmbeddingProcessorFactoryFor(tenant)
            .Create(
                arguments.Definition.Embedding,
                new Embedding(
                    arguments.Definition.Embedding,
                    dispatcher,
                    _embeddingRequestFactory,
                    _loggerFactory.CreateLogger <Embedding>()),
                arguments.Definition.InititalState,
                executionContext),
            cts.Token);


        var tasks = new TaskGroup(dispatcherTask, processorTask);
        await tasks.WaitForAllCancellingOnFirst(cts).ConfigureAwait(false);
    }