예제 #1
0
        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);
        }
예제 #2
0
 public static void Free(RabbitResponseMessage item)
 {
     item.Properties = null;
     item.Body       = null;
     item.WaitHandler.Reset();
     Pool.Store(item);
 }
예제 #3
0
        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);
        }