protected override async Task <byte[]> OnReceiveAsync(Guid correlationId, CancellationToken cancellationToken) { if (_receiver is null) { throw new NullReferenceException("There is not receiver queue."); } var sw = Stopwatch.StartNew(); var message = ReceivedMessages.GetOrAdd(correlationId, _ => RabbitResponseMessage.Rent()); Interlocked.Increment(ref _receiverThreads); await CreateReceiverConsumerAsync().ConfigureAwait(false); if (!await message.WaitHandler.WaitAsync(_receiverOptionsTimeout, cancellationToken).ConfigureAwait(false)) { throw new MessageQueueTimeoutException(_receiverOptionsTimeout, correlationId.ToString()); } if (message.Body is null) { throw new MessageQueueNotFoundException("The Message can't be retrieved, null body on CorrelationId = " + correlationId); } Core.Log.LibVerbose("Received {0} bytes from the Queue '{1}' with CorrelationId={2} at {3}ms", message.Body.Length, _clientQueues.RecvQueue.Name, correlationId, sw.Elapsed.TotalMilliseconds); if (Interlocked.Decrement(ref _receiverThreads) <= 0) { _receiverStopBuffered(); } var body = message.Body; RabbitResponseMessage.Free(message); return(body); }
public static void Free(RabbitResponseMessage item) { item.Properties = null; item.Body = null; item.WaitHandler.Reset(); Pool.Store(item); }
protected override async Task <ResponseMessage> OnReceiveAsync(Guid correlationId, CancellationToken cancellationToken) { if (_receiver == null) { throw new NullReferenceException("There is not receiver queue."); } var sw = Stopwatch.StartNew(); var message = new RabbitResponseMessage(); ReceivedMessages.TryAdd(correlationId, message); Interlocked.Increment(ref _receiverThreads); var strCorrelationId = correlationId.ToString(); if (UseSingleResponseQueue) { CreateReceiverConsumer(); } else { var recName = _receiver.Name + "_" + strCorrelationId; var pool = _routeConnection.GetOrAdd(_receiver.Route, r => new ObjectPool <RabbitMQueue>(p => new RabbitMQueue(_receiver))); var cReceiver = pool.New(); cReceiver.EnsureConnection(); cReceiver.Channel.QueueDeclare(recName, false, false, true, null); var tmpConsumer = new EventingBasicConsumer(cReceiver.Channel); tmpConsumer.Received += (ch, ea) => { var crId = Guid.Parse(ea.BasicProperties.CorrelationId); if (!ReceivedMessages.TryRemove(crId, out var rMessage)) { _receiver.Channel.BasicNack(ea.DeliveryTag, false, true); return; } rMessage.CorrelationId = crId; rMessage.Body = ea.Body; rMessage.Properties = ea.BasicProperties; rMessage.WaitHandler.Set(); cReceiver.Channel.BasicAck(ea.DeliveryTag, false); if (_correlationIdConsumers.TryRemove(crId, out var consumerTag)) { cReceiver.Channel.BasicCancel(consumerTag); } cReceiver.Channel.QueueDeleteNoWait(recName); cReceiver.AutoClose(); pool.Store(cReceiver); }; _correlationIdConsumers.TryAdd(correlationId, cReceiver.Channel.BasicConsume(recName, false, tmpConsumer)); } if (!await message.WaitHandler.WaitAsync(_receiverOptionsTimeout, cancellationToken).ConfigureAwait(false)) { if (cancellationToken.IsCancellationRequested) { cancellationToken.ThrowIfCancellationRequested(); } throw new MessageQueueTimeoutException(_receiverOptionsTimeout, strCorrelationId); } if (message.Body == null) { throw new MessageQueueNotFoundException("The Message can't be retrieved, null body on CorrelationId = " + strCorrelationId); } Core.Log.LibVerbose("Received {0} bytes from the Queue '{1}' with CorrelationId={2}", message.Body.Length, _clientQueues.RecvQueue.Name, strCorrelationId); var response = ReceiverSerializer.Deserialize <ResponseMessage>(message.Body); Core.Log.LibVerbose("Correlation Message ({0}) received at: {1}ms", strCorrelationId, sw.Elapsed.TotalMilliseconds); sw.Stop(); if (Interlocked.Decrement(ref _receiverThreads) <= 0) { _receiverStopBuffered(); } return(response); }