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; channel1.Channel.BasicPublish(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(); replyChannel.BasicPublish(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; }