ソースを参照

Merge pull request #2637 from mark-monteiro/do-not-instantiate-services-at-startup

Do not instantiate IService instances unecessarily at startup
Bond-009 5 年 前
コミット
108172c00f

+ 3 - 1
Emby.Server.Implementations/ApplicationHost.cs

@@ -43,6 +43,7 @@ using Emby.Server.Implementations.Playlists;
 using Emby.Server.Implementations.ScheduledTasks;
 using Emby.Server.Implementations.Security;
 using Emby.Server.Implementations.Serialization;
+using Emby.Server.Implementations.Services;
 using Emby.Server.Implementations.Session;
 using Emby.Server.Implementations.SocketSharp;
 using Emby.Server.Implementations.TV;
@@ -758,6 +759,7 @@ namespace Emby.Server.Implementations
             CertificateInfo = GetCertificateInfo(true);
             Certificate = GetCertificate(CertificateInfo);
 
+            serviceCollection.AddSingleton<ServiceController>();
             serviceCollection.AddSingleton<IHttpListener, WebSocketSharpListener>();
             serviceCollection.AddSingleton<IHttpServer, HttpListenerHost>();
 
@@ -1063,7 +1065,7 @@ namespace Emby.Server.Implementations
                         .Where(i => i != null)
                         .ToArray();
 
-            HttpServer.Init(GetExports<IService>(false), GetExports<IWebSocketListener>(), GetUrlPrefixes());
+            HttpServer.Init(GetExportTypes<IService>(), GetExports<IWebSocketListener>(), GetUrlPrefixes());
 
             LibraryManager.AddParts(
                 GetExports<IResolverIgnoreRule>(),

+ 10 - 9
Emby.Server.Implementations/HttpServer/HttpListenerHost.cs

@@ -60,7 +60,8 @@ namespace Emby.Server.Implementations.HttpServer
             IJsonSerializer jsonSerializer,
             IXmlSerializer xmlSerializer,
             IHttpListener socketListener,
-            ILocalizationManager localizationManager)
+            ILocalizationManager localizationManager,
+            ServiceController serviceController)
         {
             _appHost = applicationHost;
             _logger = logger;
@@ -71,6 +72,8 @@ namespace Emby.Server.Implementations.HttpServer
             _jsonSerializer = jsonSerializer;
             _xmlSerializer = xmlSerializer;
             _socketListener = socketListener;
+            ServiceController = serviceController;
+
             _socketListener.WebSocketConnected = OnWebSocketConnected;
 
             _funcParseFn = t => s => JsvReader.GetParseFn(t)(s);
@@ -90,7 +93,7 @@ namespace Emby.Server.Implementations.HttpServer
 
         public string GlobalResponse { get; set; }
 
-        public ServiceController ServiceController { get; private set; }
+        public ServiceController ServiceController { get; }
 
         public object CreateInstance(Type type)
         {
@@ -594,17 +597,15 @@ namespace Emby.Server.Implementations.HttpServer
         /// <summary>
         /// Adds the rest handlers.
         /// </summary>
-        /// <param name="services">The services.</param>
-        /// <param name="listeners"></param>
-        /// <param name="urlPrefixes"></param>
-        public void Init(IEnumerable<IService> services, IEnumerable<IWebSocketListener> listeners, IEnumerable<string> urlPrefixes)
+        /// <param name="serviceTypes">The service types to register with the <see cref="ServiceController"/>.</param>
+        /// <param name="listeners">The web socket listeners.</param>
+        /// <param name="urlPrefixes">The URL prefixes. See <see cref="UrlPrefixes"/>.</param>
+        public void Init(IEnumerable<Type> serviceTypes, IEnumerable<IWebSocketListener> listeners, IEnumerable<string> urlPrefixes)
         {
             _webSocketListeners = listeners.ToArray();
             UrlPrefixes = urlPrefixes.ToArray();
-            ServiceController = new ServiceController();
 
-            var types = services.Select(r => r.GetType());
-            ServiceController.Init(this, types);
+            ServiceController.Init(this, serviceTypes);
 
             ResponseFilters = new Action<IRequest, HttpResponse, object>[]
             {

+ 20 - 0
Emby.Server.Implementations/Services/ServiceController.cs

@@ -3,14 +3,27 @@ using System.Collections.Generic;
 using System.Threading.Tasks;
 using Emby.Server.Implementations.HttpServer;
 using MediaBrowser.Model.Services;
+using Microsoft.Extensions.Logging;
 
 namespace Emby.Server.Implementations.Services
 {
     public delegate object ActionInvokerFn(object intance, object request);
+
     public delegate void VoidActionInvokerFn(object intance, object request);
 
     public class ServiceController
     {
+        private readonly ILogger _logger;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ServiceController"/> class.
+        /// </summary>
+        /// <param name="logger">The <see cref="ServiceController"/> logger.</param>
+        public ServiceController(ILogger<ServiceController> logger)
+        {
+            _logger = logger;
+        }
+
         public void Init(HttpListenerHost appHost, IEnumerable<Type> serviceTypes)
         {
             foreach (var serviceType in serviceTypes)
@@ -21,6 +34,13 @@ namespace Emby.Server.Implementations.Services
 
         public void RegisterService(HttpListenerHost appHost, Type serviceType)
         {
+            // Make sure the provided type implements IService
+            if (!typeof(IService).IsAssignableFrom(serviceType))
+            {
+                _logger.LogWarning("Tried to register a service that does not implement IService: {ServiceType}", serviceType);
+                return;
+            }
+
             var processedReqs = new HashSet<Type>();
 
             var actions = ServiceExecGeneral.Reset(serviceType);

+ 1 - 1
MediaBrowser.Controller/Net/IHttpServer.cs

@@ -32,7 +32,7 @@ namespace MediaBrowser.Controller.Net
         /// <summary>
         /// Inits this instance.
         /// </summary>
-        void Init(IEnumerable<IService> services, IEnumerable<IWebSocketListener> listener, IEnumerable<string> urlPrefixes);
+        void Init(IEnumerable<Type> serviceTypes, IEnumerable<IWebSocketListener> listener, IEnumerable<string> urlPrefixes);
 
         /// <summary>
         /// If set, all requests will respond with this message