Пример #1
0
        private void WriteMessageToDisk(string routingKey, ServiceEventMessage message, string path)
        {
            string filename = Path.Combine(path, string.Concat(routingKey, "_", message.MessageID, ".lck"));

            lock (this)
            {
                string messageFilename = Path.ChangeExtension(filename, ".msg");
                if (!File.Exists(messageFilename))
                {
                    using (FileStream stream = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, 4096, FileOptions.None))
                    {
                        MessageFormatter messageFormatter = new MessageFormatter(stream);
                        messageFormatter.Serialise(message);
                        stream.Flush();
                        stream.Close();
                    }
                    File.Move(filename, messageFilename);
                }
            }
        }
Пример #2
0
        private void WriteQueueToDisk(Queue <QueuedMessage> queue, string path)
        {
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            MessageFormatter messageFormatter = new MessageFormatter();

            while (queue.Count > 0)
            {
                QueuedMessage queuedMessage;
                lock (queue)
                {
                    queuedMessage = queue.Dequeue();
                }
                string routingKey           = queuedMessage.RoutingKey;
                ServiceEventMessage message = queuedMessage.Message;
                if (message.MessageID == Guid.Empty)
                {
                    message.MessageID = Guid.NewGuid();
                }
                if (message.TimeStamp == 0)
                {
                    message.TimeStamp = DateTime.UtcNow.Ticks;
                }
                string filename        = Path.Combine(path, string.Format("{0}_{1}.lck", routingKey, message.MessageID));
                string messageFilename = Path.ChangeExtension(filename, ".msg");
                if (!File.Exists(messageFilename))
                {
                    using (FileStream stream = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, 4096, FileOptions.None))
                    {
                        messageFormatter.Serialise(stream, message);
                    }
                    File.Move(filename, messageFilename);
                }
            }
        }
Пример #3
0
        private void PublishFireAndForgetMessages()
        {
            bool         connectionError = false;
            MemoryStream stream          = new MemoryStream(32768);

            while (!_Terminate)
            {
                try
                {
                    connectionError = false;
                    RabbitMQConnection server = _Servers[_CurrentHostIndex];
                    _CurrentHostIndex = (_CurrentHostIndex + 1) % _ServerCount;
                    ConnectionFactory connectionFactory = new ConnectionFactory();
                    connectionFactory.uri = server.Uri;
                    if (!string.IsNullOrEmpty(server.Username))
                    {
                        connectionFactory.UserName = server.Username;
                    }
                    if (!string.IsNullOrEmpty(server.Password))
                    {
                        connectionFactory.Password = server.Password;
                    }
                    string hostname = server.Uri.DnsSafeHost;

                    MessageFormatter messageFormatter = new MessageFormatter(stream);
                    using (IConnection connection = connectionFactory.CreateConnection())
                    {
                        using (IModel asyncChannel = connection.CreateModel())
                        {
                            //asynchronousChannel.BasicReturn += new RabbitMQ.Client.Events.BasicReturnEventHandler(Channel_BasicReturn);
                            asyncChannel.ExchangeDeclare(EXCHANGE_NAME, ExchangeType.Topic, true, false, null);
                            while (!_Terminate)
                            {
                                _TriggerPublishFireAndForgetMessages.Reset();
                                int      skipCount = 0;
                                TimeSpan delay     = TimeSpan.MaxValue;
                                Dictionary <Guid, Object> skippedMessages = new Dictionary <Guid, object>();
                                while (_FireAndForgetMessages.Count > skipCount)
                                {
                                    QueuedMessage queuedMessage;
                                    lock (_FireAndForgetMessages)
                                    {
                                        queuedMessage = _FireAndForgetMessages.Dequeue();
                                    }
                                    if (queuedMessage.Message.QueueAfterTime.HasValue && (queuedMessage.Message.QueueAfterTime.Value > DateTime.UtcNow))
                                    {
                                        TimeSpan messageDelay = queuedMessage.Message.QueueAfterTime.Value.Subtract(DateTime.UtcNow);
                                        if (messageDelay < delay)
                                        {
                                            delay = messageDelay;
                                        }
                                        lock (_FireAndForgetMessages)
                                        {
                                            _FireAndForgetMessages.Enqueue(queuedMessage);
                                        }
                                        if (skippedMessages.ContainsKey(queuedMessage.Message.MessageID))
                                        {
                                            skippedMessages.Add(queuedMessage.Message.MessageID, null);
                                            skipCount++;
                                        }
                                        continue;
                                    }
                                    stream.Position = 0;
                                    messageFormatter.Serialise(queuedMessage.Message);
                                    stream.SetLength(stream.Position);
                                    stream.Position = 0;
                                    byte[]           data       = stream.ToArray();
                                    IBasicProperties properties = asyncChannel.CreateBasicProperties();
                                    properties.CorrelationId = hostname;
                                    properties.DeliveryMode  = 2;
                                    properties.MessageId     = queuedMessage.Message.MessageID.ToString();
                                    properties.ContentType   = messageFormatter.ContentType;

                                    //Transaction was only about ~14 messages a second whereas non is ~1300
                                    if (queuedMessage.Requeued)
                                    {
                                        asyncChannel.BasicPublish(string.Empty, queuedMessage.RoutingKey, properties, data);
                                    }
                                    else
                                    {
                                        asyncChannel.BasicPublish(EXCHANGE_NAME, queuedMessage.RoutingKey, properties, data);
                                    }
                                }
                                if (!_Terminate)
                                {
                                    if (delay == TimeSpan.MaxValue)
                                    {
                                        _TriggerPublishFireAndForgetMessages.WaitOne();
                                    }
                                    else
                                    {
                                        _TriggerPublishFireAndForgetMessages.WaitOne(delay);
                                    }
                                }
                            }
                            asyncChannel.Close(200, "Goodbye");
                        }
                        connection.Close();
                    }
                }
                catch (ThreadAbortException)
                {
                    break;
                }
                catch (Exception ex)
                {
                    connectionError = true;
                    ApplicationEventLog.WriteEntry("Flow", string.Format("DALRabbitMQ::PublishMessages - Exception\n{0}", ex), System.Diagnostics.EventLogEntryType.Error);
                }
                if (connectionError)
                {
                    Thread.Sleep(500);
                }
            }
        }
Пример #4
0
        private TimeSpan PublishTransactionalMessages(IModel transactionalChannel, string hostname, string exchange, string path, bool requeue)
        {
            TimeSpan         result           = TimeSpan.MaxValue;
            MessageFormatter messageFormatter = new MessageFormatter();

            string[] files     = Directory.GetFiles(path, "*.msg");
            int      skipCount = 0;

            while (files.Length > skipCount)
            {
                skipCount = 0;
                foreach (string item in files)
                {
                    if (File.Exists(item))
                    {
                        byte[] data = null;
                        try
                        {
                            data = File.ReadAllBytes(item);
                        }
                        catch
                        {
                        }
                        if (data != null)
                        {
                            if (requeue)
                            {
                                ServiceEventMessage message = messageFormatter.Deserialise(new MemoryStream(data));
                                if ((message != null) && (message.QueueAfterTime.HasValue) && (message.QueueAfterTime.Value > DateTime.UtcNow))
                                {
                                    TimeSpan delay = message.QueueAfterTime.Value.Subtract(DateTime.UtcNow);
                                    if (delay < result)
                                    {
                                        result = delay;
                                    }
                                    skipCount++;
                                    continue;
                                }
                            }
                            string messageFilename = Path.ChangeExtension(item, ".trx");
                            if (File.Exists(messageFilename))
                            {
                                DeleteMessageFile(messageFilename);
                            }
                            File.Move(item, messageFilename);
                            IBasicProperties properties = transactionalChannel.CreateBasicProperties();
                            properties.CorrelationId = hostname;
                            properties.DeliveryMode  = 2;
                            properties.ContentType   = messageFormatter.ContentType;
                            string filename   = Path.GetFileNameWithoutExtension(item);
                            string routingKey = string.Empty;
                            int    index      = filename.IndexOf('_');
                            if (index != -1)
                            {
                                routingKey = filename.Substring(0, index);
                                int nextIndex = filename.IndexOf('_', index + 1);
                                if (nextIndex == -1)
                                {
                                    properties.MessageId = filename.Substring(index + 1);
                                }
                                else
                                {
                                    properties.MessageId = filename.Substring(index + 1, nextIndex - index - 1);
                                }
                            }
                            transactionalChannel.TxSelect();
                            transactionalChannel.BasicPublish(exchange, routingKey, properties, data);
                            transactionalChannel.TxCommit();
                            DeleteMessageFile(messageFilename);
                        }
                    }
                }
                files = Directory.GetFiles(path, "*.msg");
            }
            return(result);
        }
Пример #5
0
 void IBasicConsumer.HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey, IBasicProperties properties, byte[] body)
 {
     try
     {
         if (_ProcessMessages)
         {
             Interlocked.Increment(ref _MessageHandlingCount);
             MessageFormatter    messageFormatter = new MessageFormatter();
             ServiceEventMessage message          = messageFormatter.Deserialise(new MemoryStream(body));
             lock (_Queues)
             {
                 if (_Queues.ContainsKey(consumerTag))
                 {
                     MessageQueue queue = _Queues[consumerTag];
                     message.DeliveryID = Guid.NewGuid();
                     AckMessageInfo ackMessageInfo = new AckMessageInfo();
                     ackMessageInfo.DeliveryID     = message.DeliveryID;
                     ackMessageInfo.QueueName      = queue.QueueName;
                     ackMessageInfo.DeliveryTag    = deliveryTag;
                     ackMessageInfo.TotalExpected  = queue.Handlers.Count;
                     ackMessageInfo.ChannelHandler = this;
                     queue.AddAckMessageInfo(message.DeliveryID, ackMessageInfo);
                     message.Queue = queue.QueueName;
                     for (int index = 0; index < queue.Handlers.Count; index++)
                     {
                         try
                         {
                             MessageArrivedEventHandler handler = queue.Handlers[index];
                             handler.BeginInvoke(_ConnectionFactory.HostName, message, _Subscription.InvokeCallBack, new MessageArrivedState(handler, message, queue, ackMessageInfo));
                         }
                         catch (Exception ex)
                         {
                             _Subscription.NackMessage(message);
                             ApplicationEventLog.WriteEntry("Flow", ex.ToString(), System.Diagnostics.EventLogEntryType.Error);
                         }
                     }
                     if (queue.Handlers.Count == 0)
                     {
                         Thread.Sleep(500);
                         _Model.BasicReject(deliveryTag, true);
                         Interlocked.Decrement(ref _MessageHandlingCount);
                         ApplicationEventLog.WriteEntry("Flow", string.Format("No handlers to process message {0}", consumerTag), System.Diagnostics.EventLogEntryType.Error);
                     }
                 }
                 else
                 {
                     Thread.Sleep(500);
                     _Model.BasicReject(deliveryTag, true);
                     Interlocked.Decrement(ref _MessageHandlingCount);
                     ApplicationEventLog.WriteEntry("Flow", string.Format("HandleBasicDeliver: Failed to locate queue {0}", consumerTag), System.Diagnostics.EventLogEntryType.Error);
                 }
             }
         }
     }
     catch (System.Runtime.Serialization.SerializationException)
     {
         string path = GetBadMessageDirectory();
         File.WriteAllBytes(Path.Combine(path, string.Concat(consumerTag, "_", Guid.NewGuid().ToString())), body);
         _Model.BasicReject(deliveryTag, false);
         Interlocked.Decrement(ref _MessageHandlingCount);
     }
     catch (Exception ex)
     {
         Thread.Sleep(500);
         try
         {
             if (_Model != null)
             {
                 _Model.BasicReject(deliveryTag, true);
             }
             Interlocked.Decrement(ref _MessageHandlingCount);
         }
         catch { }
         ApplicationEventLog.WriteEntry("Flow", ex.ToString(), System.Diagnostics.EventLogEntryType.Error);
     }
 }