From 67038ddd5e44e3b91005eee34a6b5e055ed0e3e1 Mon Sep 17 00:00:00 2001 From: Taloth Saldono Date: Thu, 15 Mar 2018 22:48:05 +0100 Subject: [PATCH] Cache EventAggregator Subscribers. --- .../Messaging/Events/EventAggregator.cs | 49 ++++++++++++++++--- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/src/NzbDrone.Core/Messaging/Events/EventAggregator.cs b/src/NzbDrone.Core/Messaging/Events/EventAggregator.cs index f447cf237..4f49324a9 100644 --- a/src/NzbDrone.Core/Messaging/Events/EventAggregator.cs +++ b/src/NzbDrone.Core/Messaging/Events/EventAggregator.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using NLog; @@ -14,12 +15,38 @@ namespace NzbDrone.Core.Messaging.Events private readonly Logger _logger; private readonly IServiceFactory _serviceFactory; private readonly TaskFactory _taskFactory; + private readonly Dictionary _eventSubscribers; + + private class EventSubscribers where TEvent : class, IEvent + { + private IServiceFactory _serviceFactory; + + public IHandle[] _syncHandlers; + public IHandleAsync[] _asyncHandlers; + public IHandleAsync[] _globalHandlers; + + public EventSubscribers(IServiceFactory serviceFactory) + { + _serviceFactory = serviceFactory; + + _syncHandlers = serviceFactory.BuildAll>() + .OrderBy(GetEventHandleOrder) + .ToArray(); + + _globalHandlers = serviceFactory.BuildAll>() + .ToArray(); + + _asyncHandlers = serviceFactory.BuildAll>() + .ToArray(); + } + } public EventAggregator(Logger logger, IServiceFactory serviceFactory) { _logger = logger; _serviceFactory = serviceFactory; _taskFactory = new TaskFactory(); + _eventSubscribers = new Dictionary(); } public void PublishEvent(TEvent @event) where TEvent : class, IEvent @@ -47,12 +74,20 @@ namespace NzbDrone.Core.Messaging.Events _logger.Trace("Publishing {0}", eventName); + EventSubscribers subscribers; + lock (_eventSubscribers) + { + object target; + if (!_eventSubscribers.TryGetValue(eventName, out target)) + { + _eventSubscribers[eventName] = target = new EventSubscribers(_serviceFactory); + } + + subscribers = target as EventSubscribers; + } //call synchronous handlers first. - var handlers = _serviceFactory.BuildAll>() - .OrderBy(GetEventHandleOrder) - .ToList(); - + var handlers = subscribers._syncHandlers; foreach (var handler in handlers) { try @@ -67,7 +102,7 @@ namespace NzbDrone.Core.Messaging.Events } } - foreach (var handler in _serviceFactory.BuildAll>()) + foreach (var handler in subscribers._globalHandlers) { var handlerLocal = handler; @@ -78,7 +113,7 @@ namespace NzbDrone.Core.Messaging.Events .LogExceptions(); } - foreach (var handler in _serviceFactory.BuildAll>()) + foreach (var handler in subscribers._asyncHandlers) { var handlerLocal = handler; @@ -102,7 +137,7 @@ namespace NzbDrone.Core.Messaging.Events return string.Format("{0}<{1}>", eventType.Name.Remove(eventType.Name.IndexOf('`')), eventType.GetGenericArguments()[0].Name); } - private int GetEventHandleOrder(IHandle eventHandler) where TEvent : class, IEvent + internal static int GetEventHandleOrder(IHandle eventHandler) where TEvent : class, IEvent { // TODO: Convert "Handle" to nameof(eventHandler.Handle) after .net 4.5 var method = eventHandler.GetType().GetMethod("Handle", new Type[] {typeof(TEvent)});