public void Given_Two_Queues_In_One_Process_When_One_Queue_Is_Long_Then_It_Should_Not_Block_Other_Queues() { string highPriorityTopicName = string.Format("test_high_priority_{0}", DateTime.Now.UnixNano()); const string highPriorityChannelName = "test_high_priority"; string lowPriorityTopicName = string.Format("test_low_priority_{0}", DateTime.Now.UnixNano()); const string lowPriorityChannelName = "test_low_priority"; var container = new Container(); container.Configure(x => { x.For <IHandleMessages <HighPriority <UpdateMessage> > >().Use <UpdateHandler>(); x.For <IHandleMessages <LowPriority <UpdateMessage> > >().Use <UpdateHandler>(); }); try { BusService.Start(new BusConfiguration( new StructureMapObjectBuilder(container), new NewtonsoftJsonSerializer(typeof(JsonConverter).Assembly), new MessageAuditorStub(), new MessageTypeToTopicDictionary(new Dictionary <Type, string> { { typeof(HighPriority <UpdateMessage>), highPriorityTopicName }, { typeof(LowPriority <UpdateMessage>), lowPriorityTopicName } }), new HandlerTypeToChannelDictionary(new Dictionary <Type, string> { { typeof(IHandleMessages <HighPriority <UpdateMessage> >), highPriorityChannelName }, { typeof(IHandleMessages <LowPriority <UpdateMessage> >), lowPriorityChannelName } }), defaultNsqLookupdHttpEndpoints: new[] { "127.0.0.1:4161" }, defaultThreadsPerHandler: 4, nsqConfig: new Config { LookupdPollJitter = 0, LookupdPollInterval = TimeSpan.FromSeconds(1), } )); var bus = container.GetInstance <IBus>(); var lowPriorityMessage = UpdateMessage.LowPriority(p => p.Id = "low"); var highPriorityMessage = UpdateMessage.HighPriority(p => p.Id = "high"); bus.Send(highPriorityMessage); bus.Send(lowPriorityMessage); Thread.Sleep(TimeSpan.FromSeconds(6)); UpdateHandler.Reset(); // publishing registers this nsqd as a producer, causes consumer to connect via lookup service // TODO: this test would be faster if the cosumer connected to nsqd directly, but that's not the // TODO: pattern to encourage // send 1000 low priority message var lowPriorityMessages = new List <LowPriority <UpdateMessage> >(); for (int i = 0; i < 1000; i++) { lowPriorityMessages.Add(lowPriorityMessage); } bus.SendMulti(lowPriorityMessages); // let some go through Thread.Sleep(40); int lowCountAtSendHigh = UpdateHandler.GetCount(); // send 1 high priority message bus.Send(highPriorityMessage); // wait for nsqlookupd cycle / consumer + processing time var list = UpdateHandler.GetList(); int highIndex = -1; for (int i = 0; i < list.Count; i++) { if (list[i].Id == "high") { highIndex = i; break; } } Console.WriteLine("lowCountAtSendHigh: {0}", lowCountAtSendHigh); Console.WriteLine("highIndex: {0}", highIndex); Console.WriteLine("total: {0}", list.Count); Assert.Less(lowCountAtSendHigh, 800, "lowCountAtSendHigh"); Assert.Greater(lowCountAtSendHigh, 100, "lowCountAtSendHigh"); Assert.Less(highIndex, lowCountAtSendHigh + 50, "highIndex"); // checks stats from http server var stats = _nsqdHttpClient.GetStats(); // assert high priority stats var highTopic = stats.Topics.Single(p => p.TopicName == highPriorityTopicName); var highChannel = highTopic.Channels.Single(p => p.ChannelName == highPriorityChannelName); Assert.AreEqual(2, highTopic.MessageCount, "highTopic.MessageCount"); // kickoff + 1 message Assert.AreEqual(0, highTopic.Depth, "highTopic.Depth"); Assert.AreEqual(0, highTopic.BackendDepth, "highTopic.BackendDepth"); Assert.AreEqual(2, highChannel.MessageCount, "highChannel.MessageCount"); // kickoff + 1 message Assert.AreEqual(0, highChannel.DeferredCount, "highChannel.DeferredCount"); Assert.AreEqual(0, highChannel.Depth, "highChannel.Depth"); Assert.AreEqual(0, highChannel.BackendDepth, "highChannel.BackendDepth"); Assert.AreEqual(0, highChannel.InFlightCount, "highChannel.InFlightCount"); Assert.AreEqual(0, highChannel.TimeoutCount, "highChannel.TimeoutCount"); Assert.AreEqual(0, highChannel.RequeueCount, "highChannel.RequeueCount"); // assert low priority stats var lowTopic = stats.Topics.Single(p => p.TopicName == lowPriorityTopicName); var lowChannel = lowTopic.Channels.Single(p => p.ChannelName == lowPriorityChannelName); Assert.AreEqual(1001, lowTopic.MessageCount, "lowTopic.MessageCount"); // kickoff + 1000 messages Assert.AreEqual(0, lowTopic.Depth, "lowTopic.Depth"); Assert.AreEqual(0, lowTopic.BackendDepth, "lowTopic.BackendDepth"); Assert.AreEqual(1001, lowChannel.MessageCount, "lowChannel.MessageCount"); // kickoff + 1000 messages Assert.AreEqual(0, lowChannel.DeferredCount, "lowChannel.DeferredCount"); Assert.AreEqual(0, lowChannel.Depth, "lowChannel.Depth"); Assert.AreEqual(0, lowChannel.BackendDepth, "lowChannel.BackendDepth"); Assert.AreEqual(0, lowChannel.InFlightCount, "lowChannel.InFlightCount"); Assert.AreEqual(0, lowChannel.TimeoutCount, "lowChannel.TimeoutCount"); Assert.AreEqual(0, lowChannel.RequeueCount, "lowChannel.RequeueCount"); } finally { BusService.Stop(); _nsqdHttpClient.DeleteTopic(highPriorityTopicName); _nsqLookupdHttpClient.DeleteTopic(highPriorityTopicName); _nsqdHttpClient.DeleteTopic(lowPriorityTopicName); _nsqLookupdHttpClient.DeleteTopic(lowPriorityTopicName); } }