Пример #1
0
 private void NackCallback <T>(BasicNackEventArgs ea, MessageTracker <T> messageTracker)
 {
     if (ea.Multiple)
     {
         messageTracker.SetMultipleStatus(ea.DeliveryTag, SendStatus.Failed);
     }
     else
     {
         messageTracker.SetStatus(ea.DeliveryTag, SendStatus.Failed);
     }
 }
 private void ReturnedCallback <T>(BasicReturnEventArgs ea, MessageTracker <T> messageTracker)
 {
     messageTracker.SetStatus(ea.BasicProperties.MessageId,
                              SendStatus.Unroutable,
                              string.Format("Reply Code: {0} Reply Text: {1}", ea.ReplyCode, ea.ReplyText));
 }
 private void AckCallback <T>(BasicAckEventArgs ea, MessageTracker <T> messageTracker)
 {
     messageTracker.SetStatus(ea.DeliveryTag, SendStatus.Success);
 }
        private async Task SendBatchAsync <T>(string exchange,
                                              string routingKey,
                                              List <MessageState <T> > messageStates,
                                              MessageTracker <T> messageTracker,
                                              int messageBatchSize,
                                              TimeSpan safetyPeriod)
        {
            messageTracker.AttemptsMade++;

            var factory = new ConnectionFactory()
            {
                HostName = "localhost"
            };

            factory.AutomaticRecoveryEnabled = false;

            using (var connection = factory.CreateConnection())
            {
                using (var channel = connection.CreateModel())
                {
                    channel.ConfirmSelect();
                    channel.BasicAcks     += (o, a) => AckCallback(a, messageTracker);
                    channel.BasicNacks    += (o, a) => NackCallback(a, messageTracker);
                    channel.BasicReturn   += (o, a) => ReturnedCallback(a, messageTracker);
                    channel.ModelShutdown += (o, a) => ModelShutdown(a, messageTracker);

                    int counter = 0;
                    foreach (var messageState in messageStates)
                    {
                        counter++;
                        // create the RabbitMq message from the MessagePayload (the Order class)
                        var messageJson = JsonConvert.SerializeObject(messageState.MessagePayload);
                        var body        = Encoding.UTF8.GetBytes(messageJson);
                        var properties  = channel.CreateBasicProperties();
                        properties.Persistent = true;
                        properties.MessageId  = messageState.MessageId;
                        properties.Headers    = new Dictionary <string, object>();

                        if (messageState.SendCount > 0)
                        {
                            properties.Headers.Add("republished", true);
                        }

                        // get the next sequence number (delivery tag) and register it with this MessageState object
                        var deliveryTag = channel.NextPublishSeqNo;
                        messageTracker.SetDeliveryTag(deliveryTag, messageState);
                        messageState.Status = SendStatus.PendingResponse;
                        messageState.SendCount++;

                        // send the message
                        try
                        {
                            channel.BasicPublish(exchange: exchange,
                                                 routingKey: routingKey,
                                                 basicProperties: properties,
                                                 body: body,
                                                 mandatory: true);

                            if (counter % messageBatchSize == 0)
                            {
                                channel.WaitForConfirms(TimeSpan.FromMinutes(1));
                            }
                        }
                        catch (OperationInterruptedException ex)
                        {
                            if (ex.ShutdownReason.ReplyCode == 404)
                            {
                                messageTracker.SetStatus(messageState.MessageId, SendStatus.NoExchangeFound, ex.Message);
                            }
                            else
                            {
                                messageTracker.SetStatus(messageState.MessageId, SendStatus.Failed, ex.Message);
                            }
                        }
                        catch (Exception ex)
                        {
                            messageTracker.SetStatus(messageState.MessageId, SendStatus.Failed, ex.Message);
                        }

                        if (channel.IsClosed || messageTracker.PublishingInterrupted)
                        {
                            return;
                        }
                    }

                    channel.WaitForConfirms(TimeSpan.FromMinutes(1));

                    if (safetyPeriod.Ticks > 0)
                    {
                        // add extra buffer in case of out of order last confirm
                        await Task.Delay(safetyPeriod).ConfigureAwait(false);
                    }
                }
            } // already disposed exception here
        }