예제 #1
0
        /// <inheritdoc />
        public bool TrySubscribe(
            ConsentId consentId,
            SubscriptionId subscriptionId,
            EventProcessor eventProcessor,
            EventsFromEventHorizonFetcher eventsFetcher,
            CancellationToken cancellationToken,
            out Subscription subscription)
        {
            subscription = default;
            if (_subscriptions.ContainsKey(subscriptionId))
            {
                _logger.Warning("Subscription: '{SubscriptionId}' already registered", subscriptionId);
                return(false);
            }

            subscription = new Subscription(
                consentId,
                subscriptionId,
                eventProcessor,
                eventsFetcher,
                _streamProcessorStates,
                () => Unregister(subscriptionId),
                _eventsFetcherPolicy,
                _loggerManager,
                cancellationToken);
            if (!_subscriptions.TryAdd(subscriptionId, subscription))
            {
                _logger.Warning("Subscription: '{SubscriptionId}' already registered", subscriptionId);
                subscription = default;
                return(false);
            }

            _logger.Trace("Subscription: '{SubscriptionId}' registered", subscriptionId);
            return(true);
        }
예제 #2
0
        async Task ReadEventsFromEventHorizon(
            ConsentId consentId,
            SubscriptionId subscriptionId,
            IReverseCallClient <EventHorizonConsumerToProducerMessage, EventHorizonProducerToConsumerMessage, ConsumerSubscriptionRequest, Contracts.SubscriptionResponse, ConsumerRequest, ConsumerResponse> reverseCallClient)
        {
            _logger.Information("Successfully connected event horizon with {subscriptionId}. Waiting for events to process", subscriptionId);
            var queue         = new AsyncProducerConsumerQueue <StreamEvent>();
            var eventsFetcher = new EventsFromEventHorizonFetcher(queue);

            using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(_cancellationToken);
            var tasks = new List <Task>();

            try
            {
                _subscriptions.TrySubscribe(
                    consentId,
                    subscriptionId,
                    new EventProcessor(consentId, subscriptionId, _eventHorizonEventsWriter, _eventProcessorPolicy, _logger),
                    eventsFetcher,
                    linkedTokenSource.Token,
                    out var outputtedStreamProcessor);
                using var streamProcessor = outputtedStreamProcessor;
                await streamProcessor.Initialize().ConfigureAwait(false);

                tasks.Add(Task.Run(async() =>
                {
                    await reverseCallClient.Handle(
                        (request, cancellationToken) => HandleConsumerRequest(subscriptionId, queue, request, cancellationToken),
                        linkedTokenSource.Token).ConfigureAwait(false);
                    linkedTokenSource.Cancel();
                }));
                tasks.Add(streamProcessor.Start());
            }
            catch (Exception ex)
            {
                linkedTokenSource.Cancel();
                _logger.Warning(ex, "Error occurred while initializing Subscription: {subscriptionId}", subscriptionId);
                return;
            }

            var finishedTask = await Task.WhenAny(tasks).ConfigureAwait(false);

            if (!linkedTokenSource.IsCancellationRequested)
            {
                linkedTokenSource.Cancel();
            }
            if (TryGetException(tasks, out var exception))
            {
                linkedTokenSource.Cancel();
                _logger.Warning(exception, "Error occurred while processing Subscription: {subscriptionId}", subscriptionId);
            }

            await Task.WhenAll(tasks).ConfigureAwait(false);
        }