private void ModelOnBasicReturn(object sender, BasicReturnEventArgs args) { if (LogAdapter.LogEnabled) { LogAdapter.LogDebug("RabbitChannel", "Message dropped. Message sent to exchange " + args.Exchange + " with routing key " + args.RoutingKey, null); } var ev = this.MessageUnrouted; if (ev == null) { return; } var envelope = new MessageEnvelope(args.BasicProperties, args.Body); var eventArgs = new MessageUnroutedEventArgs() { MessageEnvelope = envelope, Exchange = args.Exchange, ReplyCode = args.ReplyCode, ReplyText = args.ReplyText, RoutingKey = args.RoutingKey }; ev(eventArgs); }
public RpcHelper(IModel model, string exchange, IRabbitSerializer serializer) { _model = model; _exchange = exchange; _serializer = serializer; _routing2RetQueue = new Dictionary <string, string>(StringComparer.Ordinal); _waits = new ConcurrentDictionary <string, AutoResetEvent>(StringComparer.Ordinal); _replyData = new ConcurrentDictionary <string, MessageEnvelope>(StringComparer.Ordinal); this.ConsumerCancelled += (sender, args) => { LogAdapter.LogDebug("RpcHelper", "Consumer cancelled: " + args.ConsumerTag); }; }
// // IBasicConsumer implementation // public void HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey, IBasicProperties properties, byte[] body) { var correlationId = properties.CorrelationId; if (string.IsNullOrEmpty(correlationId)) { throw new RabbitException("Invalid correlationId: got a null or empty one"); } AutoResetEvent @event; if (!_waits.TryRemove(correlationId, out @event)) { // timeout'd - no need to move further LogAdapter.LogDebug("RpcHelper", "Could not find wait for correlation " + correlationId + " either it was timeout'ed, or the message was consumed by a outlier subscriber to " + routingKey); return; } // hold reply _replyData[correlationId] = new MessageEnvelope(properties, body) { ConsumerTag = consumerTag, DeliveryTag = deliveryTag, ExchangeName = exchange, IsRedelivery = redelivered, RoutingKey = routingKey }; try { @event.Set(); // may have been disposed } catch (Exception) { // potential object disposed MessageEnvelope val; _replyData.TryRemove(correlationId, out val); } }
private string GetOrCreateReturnQueue(string routingKey) { string queueName; if (_routing2RetQueue.TryGetValue(routingKey, out queueName)) { return(queueName); } queueName = _model.QueueDeclare(); _routing2RetQueue[routingKey] = queueName; // starts a bare metal consumer with no acks var consumerTag = _model.BasicConsume(queueName, noAck: true, consumer: this); LogAdapter.LogDebug("RpcHelper", "Started consumer " + consumerTag + " temporary queue " + queueName + " for routing " + routingKey); return(queueName); }
public MessageEnvelope CallRaw(byte[] data, string routingKey, IBasicProperties messageProperties, RpcSendOptions options) { // CreateBasicProperties doesnt need the lock var prop = messageProperties ?? _model.CreateBasicProperties(); using (var @event = new AutoResetEvent(false)) { prop.CorrelationId = Guid.NewGuid().ToString(); prop.Expiration = options.Timeout.TotalMilliseconds.ToString(); _waits[prop.CorrelationId] = @event; lock (_model) { var returnQueue = GetOrCreateReturnQueue(routingKey); prop.ReplyTo = returnQueue; } lock (_model) { _model.BasicPublish(_exchange, routingKey, prop, data); } if ([email protected](options.Timeout)) { MessageEnvelope val; _replyData.TryRemove(prop.CorrelationId, out val); LogAdapter.LogDebug("RpcHelper", "Timeout'ed correlation id " + prop.CorrelationId + " for " + routingKey); throw new TimeoutException("Timeout waiting for reply."); } MessageEnvelope reply; _replyData.TryRemove(prop.CorrelationId, out reply); return(reply); } }
private void OnProc() { try { while (!_closed) { var args = base.Queue.Dequeue(); if (args == null) { continue; } if (_consumers.Count == 0) { // throwing out messages due to lack of consumers if (LogAdapter.LogEnabled) { LogAdapter.LogDebug(this.GetType().FullName, "SharedQueueConsumer dropping message due to lack of consumers subscribed"); } continue; } PublishToConsumers(args); } } catch (Exception e) { if (LogAdapter.LogEnabled) { LogAdapter.LogError(this.GetType().FullName, "SharedQueueConsumer error ", e); } } }