Ejemplo n.º 1
0
        public async Task TestReleaseConsumerRace()
        {
            var connectionFactory = new CachingConnectionFactory("localhost");
            var container         = new DirectReplyToMessageListenerContainer(null, connectionFactory);

            var latch = new CountdownEvent(1);

            container.MessageListener = new EmptyListener();
            var mockMessageListener = new MockChannelAwareMessageListener(container.MessageListener, latch);

            container.SetChannelAwareMessageListener(mockMessageListener);

            var foobytes = EncodingUtils.GetDefaultEncoding().GetBytes("foo");
            var barbytes = EncodingUtils.GetDefaultEncoding().GetBytes("bar");
            await container.Start();

            Assert.True(container._startedLatch.Wait(TimeSpan.FromSeconds(10)));

            var channel1 = container.GetChannelHolder();
            var props    = channel1.Channel.CreateBasicProperties();

            props.ReplyTo = Address.AMQ_RABBITMQ_REPLY_TO;
            RC.IModelExensions.BasicPublish(channel1.Channel, string.Empty, TEST_RELEASE_CONSUMER_Q, props, foobytes);
            var replyChannel = connectionFactory.CreateConnection().CreateChannel(false);
            var request      = replyChannel.BasicGet(TEST_RELEASE_CONSUMER_Q, true);
            var n            = 0;

            while (n++ < 100 && request == null)
            {
                Thread.Sleep(100);
                request = replyChannel.BasicGet(TEST_RELEASE_CONSUMER_Q, true);
            }

            Assert.NotNull(request);
            props = channel1.Channel.CreateBasicProperties();
            RC.IModelExensions.BasicPublish(replyChannel, string.Empty, request.BasicProperties.ReplyTo, props, barbytes);
            replyChannel.Close();
            Assert.True(latch.Wait(TimeSpan.FromSeconds(10)));

            var channel2 = container.GetChannelHolder();

            Assert.Same(channel1.Channel, channel2.Channel);
            container.ReleaseConsumerFor(channel1, false, null); // simulate race for future timeout/cancel and onMessage()
            var inUse = container._inUseConsumerChannels;

            Assert.Single(inUse);
            container.ReleaseConsumerFor(channel2, false, null);
            Assert.Empty(inUse);
            await container.Stop();

            connectionFactory.Destroy();
        }
 public ChannelAwareMessageListener(DirectReplyToMessageListenerContainer container, IMessageListener listener)
 {
     _container = container;
     _listener  = listener;
 }