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