Пример #1
0
        public override Task HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey,
                                                IBasicProperties properties, byte[] body)
        {
            var @event = new BasicDeliverEventArgs(consumerTag, deliveryTag, redelivered, exchange, routingKey, properties, body);

            try
            {
                var task = new Task(() =>
                {
                    try
                    {
                        var message = Message <T> .Create(_channel, _options.Exchange, _options.Queue, RoutingKey.Create(routingKey), _options.Serializer, @event,
                                                          (OnDone, OnFail));
                        using var scope = _scopeFactory.CreateScope();
                        try
                        {
                            _options.OnNext(scope, message).GetAwaiter().GetResult();
                            if (_options.AutoAck)
                            {
                                message.Complete();
                            }
                        }
                        catch (Exception exception)
                        {
                            message.Fail(exception);
                        }
                    }
                    catch (Exception exception)
                    {
                        _logger?.WriteException(nameof(Consumer <T>), exception,
                                                new KeyValuePair <string, object>("Event", Encoding.UTF8.GetString(@event.Body)));
                        var failedQueue      = _options.Queue.CreateFailedQueue();
                        var failedRoutingKey = RoutingKey.Create(failedQueue.Name.Value);
                        _connection.Publish(Exchange.Default, failedQueue, failedRoutingKey,
                                            ErrorMessage.Create(@event.Body, @event.BasicProperties));
                        _channel.BasicNack(@event.DeliveryTag, false, false);
                    }
                });
                _tasks.Add(task);
            }
            catch (Exception ex)
            {
                _logger?.WriteException(typeof(T).Name, ex,
                                        new KeyValuePair <string, object>("args", @event));
                _channel.BasicNack(@event.DeliveryTag, false, true);
            }

            return(Task.CompletedTask);
        }
Пример #2
0
        private void PublishBufferOnCleared(IEnumerable <BatchItem> removedItems)
        {
            var items = removedItems.ToList();

            try
            {
                Policy
                .Handle <Exception>()
                .WaitAndRetry(
                    _options.Value.PublishMaxRetry,
                    _ => TimeSpan.FromMilliseconds(_options.Value.PublishRetryDelayInMilliseconds),
                    (exception, span) =>
                {
                    _logger?.WriteException("Publisher", exception,
                                            new KeyValuePair <string, object>("Events", removedItems));
                })
                .Execute(() =>
                {
                    using var channel = PublisherConnection.CreateModel();
                    channel.ConfirmSelect();

                    var batch = channel.CreateBasicPublishBatch();
                    try
                    {
                        foreach (var group in items.GroupBy(x => (x.Exchange, x.Queue, x.RoutingKey)))
                        {
                            var(exchange, queue, routingKey) = @group.Key;
                            exchange.Declare(channel);
                            queue?.Declare(channel);
                            queue?.Bind(channel, exchange, routingKey);
                            foreach (var item in @group)
                            {
                                var(body, basicProperties) =
                                    item.Message.GetData(channel, _serializer);
                                batch.Add(exchange.Name.Value, routingKey.Value, false,
                                          basicProperties, body);
                            }
                        }

                        batch.Publish();
                    }
                    finally
                    {
                        channel.WaitForConfirmsOrDie();
                        channel.Close();
                    }
                });

                PublishSuccessed?.Invoke(items.AsReadOnly());
            }
            catch (Exception ex)
            {
                _logger?.WriteException(nameof(PublishBufferOnCleared), ex,
                                        new KeyValuePair <string, object>("Events", items));
                if (PublishFailed == null)
                {
                    throw;
                }
                PublishFailed.Invoke(items.AsReadOnly(), ex);
            }
        }