public void Does_process_all_messages_and_Starts_Stops_correctly_with_multiple_threads_racing()
        {
            mqHost = CreateMqHost();

            var reverseCalled = 0;
            var rot13Called   = 0;

            mqHost.RegisterHandler <Reverse>(x => { reverseCalled++; return(x.GetBody().Value.Reverse()); });
            mqHost.RegisterHandler <Rot13>(x => { rot13Called++; return(x.GetBody().Value.ToRot13()); });

            var mqClient = mqHost.CreateMessageQueueClient();

            mqClient.Publish(new Reverse {
                Value = "Hello"
            });
            mqClient.Publish(new Reverse {
                Value = "World"
            });
            mqClient.Publish(new Rot13 {
                Value = "ServiceStack"
            });

            mqHost.Start();
            Thread.Sleep(3000);
            Assert.That(mqHost.GetStatus(), Is.EqualTo("Started"));
            Assert.That(mqHost.GetStats().TotalMessagesProcessed, Is.EqualTo(3));

            mqClient.Publish(new Reverse {
                Value = "Foo"
            });
            mqClient.Publish(new Rot13 {
                Value = "Bar"
            });

            10.Times(x => ThreadPool.QueueUserWorkItem(y => mqHost.Start()));
            Assert.That(mqHost.GetStatus(), Is.EqualTo("Started"));

            5.Times(x => ThreadPool.QueueUserWorkItem(y => mqHost.Stop()));
            Thread.Sleep(3000);
            Assert.That(mqHost.GetStatus(), Is.EqualTo("Stopped").Or.EqualTo("Stopping"));

            10.Times(x => ThreadPool.QueueUserWorkItem(y => mqHost.Start()));
            Thread.Sleep(3000);
            Assert.That(mqHost.GetStatus(), Is.EqualTo("Started"));

            Debug.WriteLine("\n" + mqHost.GetStats());

            Assert.That(mqHost.GetStats().TotalMessagesProcessed, Is.EqualTo(5));
            Assert.That(reverseCalled, Is.EqualTo(3));
            Assert.That(rot13Called, Is.EqualTo(2));

            mqHost.Dispose();
        }
        public void Only_allows_1_BgThread_to_run_at_a_time()
        {
            mqHost = CreateMqHost();

            mqHost.RegisterHandler <Reverse>(x => x.GetBody().Value.Reverse());
            mqHost.RegisterHandler <Rot13>(x => x.GetBody().Value.ToRot13());

            5.Times(x => ThreadPool.QueueUserWorkItem(y => mqHost.Start()));
            Thread.Sleep(1000);
            Assert.That(mqHost.GetStatus(), Is.EqualTo("Started"));
            Assert.That(mqHost.BgThreadCount, Is.EqualTo(1));

            10.Times(x => ThreadPool.QueueUserWorkItem(y => mqHost.Stop()));
            Thread.Sleep(1000);
            Assert.That(mqHost.GetStatus(), Is.EqualTo("Stopped"));

            ThreadPool.QueueUserWorkItem(y => mqHost.Start());
            Thread.Sleep(1000);
            Assert.That(mqHost.GetStatus(), Is.EqualTo("Started"));

            Assert.That(mqHost.BgThreadCount, Is.EqualTo(2));

            Debug.WriteLine(mqHost.GetStats());

            mqHost.Dispose();
        }
        public void Does_process_messages_sent_before_it_was_started()
        {
            var reverseCalled = 0;

            mqHost = CreateMqHost();
            mqHost.RegisterHandler <Reverse>(x => { reverseCalled++; return(x.GetBody().Value.Reverse()); });

            var mqClient = mqHost.CreateMessageQueueClient();

            Publish_4_messages(mqClient);

            mqHost.Start();
            Thread.Sleep(3000);

            Assert.That(mqHost.GetStats().TotalMessagesProcessed, Is.EqualTo(4));
            Assert.That(reverseCalled, Is.EqualTo(4));

            mqHost.Dispose();
        }
        public void Does_retry_messages_with_errors_by_RetryCount()
        {
            var retryCount   = 3;
            var totalRetries = 1 + retryCount;             //in total, inc. first try

            mqHost = CreateMqHost(retryCount);

            var reverseCalled = 0;
            var rot13Called   = 0;

            mqHost.RegisterHandler <Reverse>(x => { reverseCalled++; return(x.GetBody().Value.Reverse()); });
            mqHost.RegisterHandler <Rot13>(x => { rot13Called++; return(x.GetBody().Value.ToRot13()); });
            mqHost.RegisterHandler <AlwaysThrows>(x => { throw new Exception("Always Throwing! " + x.GetBody().Value); });
            mqHost.Start();
            Thread.Sleep(3000);

            var mqClient = mqHost.CreateMessageQueueClient();

            mqClient.Publish(new Reverse {
                Value = "Hello"
            });
            mqClient.Publish(new Reverse {
                Value = "World"
            });
            mqClient.Publish(new Rot13 {
                Value = "ServiceStack"
            });
            mqClient.Publish(new AlwaysThrows {
                Value = "1st"
            });

            Thread.Sleep(3000);

            Assert.That(mqHost.GetStats().TotalMessagesFailed, Is.EqualTo(1 * totalRetries));
            Assert.That(mqHost.GetStats().TotalMessagesProcessed, Is.EqualTo(2 + 1));

            mqClient.Publish(new Reverse {
                Value = "Hello"
            });
            mqClient.Publish(new Reverse {
                Value = "World"
            });
            mqClient.Publish(new Rot13 {
                Value = "ServiceStack"
            });

            5.Times(x => mqClient.Publish(new AlwaysThrows {
                Value = "#" + x
            }));

            Thread.Sleep(10000);

            Debug.WriteLine(mqHost.GetStatsDescription());

            Assert.That(mqHost.GetStats().TotalMessagesFailed, Is.EqualTo((1 + 5) * totalRetries));
            Assert.That(mqHost.GetStats().TotalMessagesProcessed, Is.EqualTo(6));

            Assert.That(reverseCalled, Is.EqualTo(2 + 2));
            Assert.That(rot13Called, Is.EqualTo(1 + 1));

            mqHost.Dispose();
        }
		public void Does_process_messages_sent_before_it_was_started()
		{
			var reverseCalled = 0;

			mqHost = CreateMqHost();
			mqHost.RegisterHandler<Reverse>(x => { reverseCalled++; return x.GetBody().Value.Reverse(); });

			var mqClient = mqHost.CreateMessageQueueClient();
			Publish_4_messages(mqClient);

			mqHost.Start();
			Thread.Sleep(3000);

			Assert.That(mqHost.GetStats().TotalMessagesProcessed, Is.EqualTo(4));
			Assert.That(reverseCalled, Is.EqualTo(4));

            mqHost.Dispose();
        }
		public void Does_retry_messages_with_errors_by_RetryCount()
		{
			var retryCount = 3;
			var totalRetries = 1 + retryCount; //in total, inc. first try

			mqHost = CreateMqHost(retryCount);

			var reverseCalled = 0;
			var rot13Called = 0;

			mqHost.RegisterHandler<Reverse>(x => { reverseCalled++; return x.GetBody().Value.Reverse(); });
			mqHost.RegisterHandler<Rot13>(x => { rot13Called++; return x.GetBody().Value.ToRot13(); });
			mqHost.RegisterHandler<AlwaysThrows>(x => { throw new Exception("Always Throwing! " + x.GetBody().Value); });
			mqHost.Start();
            Thread.Sleep(3000);

			var mqClient = mqHost.CreateMessageQueueClient();
            mqClient.Publish(new Reverse { Value = "Hello" });
            mqClient.Publish(new Reverse { Value = "World" });
            mqClient.Publish(new Rot13 { Value = "ServiceStack" });
            mqClient.Publish(new AlwaysThrows { Value = "1st" });

            Thread.Sleep(3000);

		    Assert.That(mqHost.GetStats().TotalMessagesFailed, Is.EqualTo(1 * totalRetries));
			Assert.That(mqHost.GetStats().TotalMessagesProcessed, Is.EqualTo(2 + 1));

            mqClient.Publish(new Reverse { Value = "Hello" });
            mqClient.Publish(new Reverse { Value = "World" });
            mqClient.Publish(new Rot13 { Value = "ServiceStack" });

			5.Times(x => mqClient.Publish(new AlwaysThrows { Value = "#" + x }));

			Thread.Sleep(10000);

			Debug.WriteLine(mqHost.GetStatsDescription());

			Assert.That(mqHost.GetStats().TotalMessagesFailed, Is.EqualTo((1 + 5) * totalRetries));
			Assert.That(mqHost.GetStats().TotalMessagesProcessed, Is.EqualTo(6));

			Assert.That(reverseCalled, Is.EqualTo(2 + 2));
			Assert.That(rot13Called, Is.EqualTo(1 + 1));

            mqHost.Dispose();
		}
		public void Only_allows_1_BgThread_to_run_at_a_time()
		{
			mqHost = CreateMqHost();

			mqHost.RegisterHandler<Reverse>(x => x.GetBody().Value.Reverse());
			mqHost.RegisterHandler<Rot13>(x => x.GetBody().Value.ToRot13());

			5.Times(x => ThreadPool.QueueUserWorkItem(y => mqHost.Start()));
			Thread.Sleep(1000);
			Assert.That(mqHost.GetStatus(), Is.EqualTo("Started"));
			Assert.That(mqHost.BgThreadCount, Is.EqualTo(1));

			10.Times(x => ThreadPool.QueueUserWorkItem(y => mqHost.Stop()));
			Thread.Sleep(1000);
			Assert.That(mqHost.GetStatus(), Is.EqualTo("Stopped"));

			ThreadPool.QueueUserWorkItem(y => mqHost.Start());
			Thread.Sleep(1000);
			Assert.That(mqHost.GetStatus(), Is.EqualTo("Started"));

			Assert.That(mqHost.BgThreadCount, Is.EqualTo(2));

			Debug.WriteLine(mqHost.GetStats());

			mqHost.Dispose();
		}
		public void Does_process_all_messages_and_Starts_Stops_correctly_with_multiple_threads_racing()
		{
			mqHost = CreateMqHost();

			var reverseCalled = 0;
			var rot13Called = 0;

			mqHost.RegisterHandler<Reverse>(x => { reverseCalled++; return x.GetBody().Value.Reverse(); });
			mqHost.RegisterHandler<Rot13>(x => { rot13Called++; return x.GetBody().Value.ToRot13(); });

			var mqClient = mqHost.CreateMessageQueueClient();
			mqClient.Publish(new Reverse { Value = "Hello" });
			mqClient.Publish(new Reverse { Value = "World" });
			mqClient.Publish(new Rot13 { Value = "ServiceStack" });

			mqHost.Start();
			Thread.Sleep(3000);
			Assert.That(mqHost.GetStatus(), Is.EqualTo("Started"));
			Assert.That(mqHost.GetStats().TotalMessagesProcessed, Is.EqualTo(3));

			mqClient.Publish(new Reverse { Value = "Foo" });
			mqClient.Publish(new Rot13 { Value = "Bar" });

			10.Times(x => ThreadPool.QueueUserWorkItem(y => mqHost.Start()));
			Assert.That(mqHost.GetStatus(), Is.EqualTo("Started"));

			5.Times(x => ThreadPool.QueueUserWorkItem(y => mqHost.Stop()));
			Thread.Sleep(3000);
			Assert.That(mqHost.GetStatus(), Is.EqualTo("Stopped").Or.EqualTo("Stopping"));

			10.Times(x => ThreadPool.QueueUserWorkItem(y => mqHost.Start()));
			Thread.Sleep(3000);
			Assert.That(mqHost.GetStatus(), Is.EqualTo("Started"));

			Debug.WriteLine("\n" + mqHost.GetStats());

			Assert.That(mqHost.GetStats().TotalMessagesProcessed, Is.EqualTo(5));
			Assert.That(reverseCalled, Is.EqualTo(3));
			Assert.That(rot13Called, Is.EqualTo(2));

			mqHost.Dispose();
		}