/// <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); }
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); }