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