Пример #1
0
        public static ConsumerDto ToConsumerDto(this ProxyConsumer proxyConsumer)
        {
            var consumerDto = new ConsumerDto
            {
                Id                    = proxyConsumer.Id,
                ServiceName           = proxyConsumer.GateConsumer.ServiceName,
                TopicName             = proxyConsumer.GateConsumer.TopicName,
                Endpoint              = proxyConsumer.Endpoint,
                IsStarted             = proxyConsumer.GateConsumer.IsStarted,
                MaxConcurrentMessages = proxyConsumer.GateConsumer.MaxConcurrentMessages,
                AbortTime             = proxyConsumer.AbortTime,
                RestartCount          = proxyConsumer.RestartCount,
                RestartDelayInSeconds = proxyConsumer.RestartDelayInSeconds
            };


            if (proxyConsumer.RestartTask != null && proxyConsumer.RestartTask.IsCompletedSuccessfully)
            {
                consumerDto.RestartTaskStatus = "COMPLETED_SUCCESSFULLY";
            }
            if (proxyConsumer.RestartTask != null && proxyConsumer.RestartTask.IsFaulted)
            {
                consumerDto.RestartTaskStatus = "FAULTED";
            }
            if (proxyConsumer.RestartTask != null && !proxyConsumer.RestartTask.IsCompleted)
            {
                consumerDto.RestartTaskStatus = "RUNNING";
            }

            return(consumerDto);
        }
Пример #2
0
        public async Task <ProxyConsumer> SubscribeConsumerAsync(
            string serviceName,
            string topicName,
            Uri endpoint,
            int maxConcurrentMessages,
            int restartDelayInSeconds,
            int restartCount,
            CancellationToken cancellationToken = default)
        {
            serviceName = serviceName ?? throw new ArgumentNullException(nameof(serviceName));
            topicName   = topicName ?? throw new ArgumentNullException(nameof(topicName));
            endpoint    = endpoint ?? throw new ArgumentNullException(nameof(endpoint));
            if (!endpoint.IsAbsoluteUri)
            {
                throw new ArgumentException("Endpoint uri must be absolute", nameof(endpoint));
            }

            var consumerId = $"{serviceName}_{topicName}_{endpoint}".ToSha256();

            var proxyConsumer = new ProxyConsumer();

            if (!_proxyConsumers.TryAdd(consumerId, proxyConsumer))
            {
                throw new InvalidOperationException("Consumer already exists");
            }

            try
            {
                proxyConsumer.Id                          = consumerId;
                proxyConsumer.Endpoint                    = endpoint;
                proxyConsumer.AbortTime                   = null;
                proxyConsumer.RestartDelayInSeconds       = restartDelayInSeconds;
                proxyConsumer.RestartCount                = restartCount;
                proxyConsumer.HttpClient                  = _httpClientFactory.CreateClient();
                proxyConsumer.UnsubscribeCompletionSource = null;
                proxyConsumer.GateConsumer                = _gateFactory.CreateConsumer <GateRequest, GateResponse>(serviceName,
                                                                                                                    topicName, async(genericContext, ct) =>
                {
                    var httpRequestMessage  = genericContext.Message.ToHttpRequestMessage(endpoint);
                    var httpResponseMessage = await proxyConsumer.HttpClient.SendAsync(httpRequestMessage, ct);
                    if (!httpResponseMessage.IsSuccessStatusCode && !genericContext.IsRequest)
                    {
                        if (!_fallbackServices.Any())
                        {
                            httpResponseMessage.EnsureSuccessStatusCode();
                        }


                        var fallbackExceptions = new List <Exception>();
                        foreach (var fallbackService in _fallbackServices)
                        {
                            try
                            {
                                await fallbackService.SendAsync(serviceName, topicName, genericContext.Message, ct);
                                break;
                            }
                            catch (Exception ex)
                            {
                                fallbackExceptions.Add(ex);
                            }
                        }

                        if (fallbackExceptions.Any())
                        {
                            throw new AggregateException("Can not send message to service or fallbacks", fallbackExceptions);
                        }
                    }

                    if (genericContext.IsRequest)
                    {
                        genericContext.Reply = await httpResponseMessage.ToGateResponseAsync();
                    }
                }, () =>
                {
                    proxyConsumer.AbortTime = DateTime.Now;
                    if (proxyConsumer.UnsubscribeCompletionSource != null)
                    {
                        proxyConsumer.UnsubscribeCompletionSource.TrySetResult(true);
                    }
                    else
                    {
                        proxyConsumer.RestartCancellationTokenSource = new CancellationTokenSource();
                        proxyConsumer.RestartTask = RestartHandler(consumerId);
                    }
                }, false, maxConcurrentMessages);

                await proxyConsumer.GateConsumer.StartConsumeAsync(cancellationToken);

                return(proxyConsumer);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error starting consumer");
                _proxyConsumers.TryRemove(consumerId, out _);
                throw;
            }
        }