more granular Concurrency control.

indexer calls are done fully paralleled.
events are dispatched on max of 2 threads.
This commit is contained in:
Keivan Beigi 2013-05-29 18:35:26 -07:00
commit 9181b1bb91
12 changed files with 377 additions and 37 deletions

View file

@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using System.Threading;
using Moq;
using NUnit.Framework;
using NzbDrone.Common.Messaging;
using NzbDrone.Test.Common;
using FluentAssertions;
namespace NzbDrone.Common.Test.EventingTests
{
@ -16,6 +18,8 @@ namespace NzbDrone.Common.Test.EventingTests
private Mock<IHandle<EventB>> HandlerB1;
private Mock<IHandle<EventB>> HandlerB2;
private Mock<IHandleAsync<EventA>> AsyncHandlerA1;
[SetUp]
public void Setup()
@ -25,6 +29,8 @@ namespace NzbDrone.Common.Test.EventingTests
HandlerB1 = new Mock<IHandle<EventB>>();
HandlerB2 = new Mock<IHandle<EventB>>();
AsyncHandlerA1 = new Mock<IHandleAsync<EventA>>();
Mocker.GetMock<IServiceFactory>()
.Setup(c => c.BuildAll<IHandle<EventA>>())
.Returns(new List<IHandle<EventA>> { HandlerA1.Object, HandlerA2.Object });
@ -79,6 +85,50 @@ namespace NzbDrone.Common.Test.EventingTests
ExceptionVerification.ExpectedErrors(1);
}
[Test]
public void should_queue_multiple_async_events()
{
var eventA = new EventA();
var handlers = new List<IHandleAsync<EventA>>
{
AsyncHandlerA1.Object,
AsyncHandlerA1.Object,
AsyncHandlerA1.Object,
AsyncHandlerA1.Object,
AsyncHandlerA1.Object,
AsyncHandlerA1.Object,
AsyncHandlerA1.Object,
};
Mocker.GetMock<IServiceFactory>()
.Setup(c => c.BuildAll<IHandle<EventA>>())
.Returns(new List<IHandle<EventA>>());
Mocker.GetMock<IServiceFactory>()
.Setup(c => c.BuildAll<IHandleAsync<EventA>>())
.Returns(handlers);
var counter = new ConcurrencyCounter(handlers.Count);
AsyncHandlerA1.Setup(c => c.HandleAsync(It.IsAny<EventA>()))
.Callback<EventA>(c =>
{
var id = counter.Start();
Thread.Sleep(1000);
counter.Stop(id);
});
Subject.PublishEvent(eventA);
counter.WaitForAllItems();
counter.MaxThreads.Should().Be(2);
}
}