瀏覽代碼

Merge pull request #10337 from barronpm/system-manager

Bond-009 1 年之前
父節點
當前提交
fc1f0a31a1

+ 5 - 75
Emby.Server.Implementations/ApplicationHost.cs

@@ -101,7 +101,6 @@ using Microsoft.AspNetCore.Mvc;
 using Microsoft.EntityFrameworkCore;
 using Microsoft.EntityFrameworkCore;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 using Prometheus.DotNetRuntime;
 using Prometheus.DotNetRuntime;
 using static MediaBrowser.Controller.Extensions.ConfigurationExtensions;
 using static MediaBrowser.Controller.Extensions.ConfigurationExtensions;
@@ -133,7 +132,7 @@ namespace Emby.Server.Implementations
         /// <value>All concrete types.</value>
         /// <value>All concrete types.</value>
         private Type[] _allConcreteTypes;
         private Type[] _allConcreteTypes;
 
 
-        private bool _disposed = false;
+        private bool _disposed;
 
 
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="ApplicationHost"/> class.
         /// Initializes a new instance of the <see cref="ApplicationHost"/> class.
@@ -184,26 +183,16 @@ namespace Emby.Server.Implementations
 
 
         public bool CoreStartupHasCompleted { get; private set; }
         public bool CoreStartupHasCompleted { get; private set; }
 
 
-        public virtual bool CanLaunchWebBrowser => Environment.UserInteractive
-            && !_startupOptions.IsService
-            && (OperatingSystem.IsWindows() || OperatingSystem.IsMacOS());
-
         /// <summary>
         /// <summary>
         /// Gets the <see cref="INetworkManager"/> singleton instance.
         /// Gets the <see cref="INetworkManager"/> singleton instance.
         /// </summary>
         /// </summary>
         public INetworkManager NetManager { get; private set; }
         public INetworkManager NetManager { get; private set; }
 
 
-        /// <summary>
-        /// Gets a value indicating whether this instance has changes that require the entire application to restart.
-        /// </summary>
-        /// <value><c>true</c> if this instance has pending application restart; otherwise, <c>false</c>.</value>
-        public bool HasPendingRestart { get; private set; }
-
         /// <inheritdoc />
         /// <inheritdoc />
-        public bool IsShuttingDown { get; private set; }
+        public bool HasPendingRestart { get; private set; }
 
 
         /// <inheritdoc />
         /// <inheritdoc />
-        public bool ShouldRestart { get; private set; }
+        public bool ShouldRestart { get; set; }
 
 
         /// <summary>
         /// <summary>
         /// Gets the logger.
         /// Gets the logger.
@@ -507,6 +496,8 @@ namespace Emby.Server.Implementations
             serviceCollection.AddSingleton<IFileSystem, ManagedFileSystem>();
             serviceCollection.AddSingleton<IFileSystem, ManagedFileSystem>();
             serviceCollection.AddSingleton<IShortcutHandler, MbLinkShortcutHandler>();
             serviceCollection.AddSingleton<IShortcutHandler, MbLinkShortcutHandler>();
 
 
+            serviceCollection.AddScoped<ISystemManager, SystemManager>();
+
             serviceCollection.AddSingleton<TmdbClientManager>();
             serviceCollection.AddSingleton<TmdbClientManager>();
 
 
             serviceCollection.AddSingleton(NetManager);
             serviceCollection.AddSingleton(NetManager);
@@ -850,24 +841,6 @@ namespace Emby.Server.Implementations
             }
             }
         }
         }
 
 
-        /// <inheritdoc />
-        public void Restart()
-        {
-            ShouldRestart = true;
-            Shutdown();
-        }
-
-        /// <inheritdoc />
-        public void Shutdown()
-        {
-            Task.Run(async () =>
-            {
-                await Task.Delay(100).ConfigureAwait(false);
-                IsShuttingDown = true;
-                Resolve<IHostApplicationLifetime>().StopApplication();
-            });
-        }
-
         /// <summary>
         /// <summary>
         /// Gets the composable part assemblies.
         /// Gets the composable part assemblies.
         /// </summary>
         /// </summary>
@@ -923,49 +896,6 @@ namespace Emby.Server.Implementations
 
 
         protected abstract IEnumerable<Assembly> GetAssembliesWithPartsInternal();
         protected abstract IEnumerable<Assembly> GetAssembliesWithPartsInternal();
 
 
-        /// <summary>
-        /// Gets the system status.
-        /// </summary>
-        /// <param name="request">Where this request originated.</param>
-        /// <returns>SystemInfo.</returns>
-        public SystemInfo GetSystemInfo(HttpRequest request)
-        {
-            return new SystemInfo
-            {
-                HasPendingRestart = HasPendingRestart,
-                IsShuttingDown = IsShuttingDown,
-                Version = ApplicationVersionString,
-                WebSocketPortNumber = HttpPort,
-                CompletedInstallations = Resolve<IInstallationManager>().CompletedInstallations.ToArray(),
-                Id = SystemId,
-                ProgramDataPath = ApplicationPaths.ProgramDataPath,
-                WebPath = ApplicationPaths.WebPath,
-                LogPath = ApplicationPaths.LogDirectoryPath,
-                ItemsByNamePath = ApplicationPaths.InternalMetadataPath,
-                InternalMetadataPath = ApplicationPaths.InternalMetadataPath,
-                CachePath = ApplicationPaths.CachePath,
-                CanLaunchWebBrowser = CanLaunchWebBrowser,
-                TranscodingTempPath = ConfigurationManager.GetTranscodePath(),
-                ServerName = FriendlyName,
-                LocalAddress = GetSmartApiUrl(request),
-                SupportsLibraryMonitor = true,
-                PackageName = _startupOptions.PackageName
-            };
-        }
-
-        public PublicSystemInfo GetPublicSystemInfo(HttpRequest request)
-        {
-            return new PublicSystemInfo
-            {
-                Version = ApplicationVersionString,
-                ProductName = ApplicationProductName,
-                Id = SystemId,
-                ServerName = FriendlyName,
-                LocalAddress = GetSmartApiUrl(request),
-                StartupWizardCompleted = ConfigurationManager.CommonConfiguration.IsStartupWizardCompleted
-            };
-        }
-
         /// <inheritdoc/>
         /// <inheritdoc/>
         public string GetSmartApiUrl(IPAddress remoteAddr)
         public string GetSmartApiUrl(IPAddress remoteAddr)
         {
         {

+ 108 - 0
Emby.Server.Implementations/SystemManager.cs

@@ -0,0 +1,108 @@
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Updates;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Model.System;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Hosting;
+
+namespace Emby.Server.Implementations;
+
+/// <inheritdoc />
+public class SystemManager : ISystemManager
+{
+    private readonly IHostApplicationLifetime _applicationLifetime;
+    private readonly IServerApplicationHost _applicationHost;
+    private readonly IServerApplicationPaths _applicationPaths;
+    private readonly IServerConfigurationManager _configurationManager;
+    private readonly IStartupOptions _startupOptions;
+    private readonly IInstallationManager _installationManager;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="SystemManager"/> class.
+    /// </summary>
+    /// <param name="applicationLifetime">Instance of <see cref="IHostApplicationLifetime"/>.</param>
+    /// <param name="applicationHost">Instance of <see cref="IServerApplicationHost"/>.</param>
+    /// <param name="applicationPaths">Instance of <see cref="IServerApplicationPaths"/>.</param>
+    /// <param name="configurationManager">Instance of <see cref="IServerConfigurationManager"/>.</param>
+    /// <param name="startupOptions">Instance of <see cref="IStartupOptions"/>.</param>
+    /// <param name="installationManager">Instance of <see cref="IInstallationManager"/>.</param>
+    public SystemManager(
+        IHostApplicationLifetime applicationLifetime,
+        IServerApplicationHost applicationHost,
+        IServerApplicationPaths applicationPaths,
+        IServerConfigurationManager configurationManager,
+        IStartupOptions startupOptions,
+        IInstallationManager installationManager)
+    {
+        _applicationLifetime = applicationLifetime;
+        _applicationHost = applicationHost;
+        _applicationPaths = applicationPaths;
+        _configurationManager = configurationManager;
+        _startupOptions = startupOptions;
+        _installationManager = installationManager;
+    }
+
+    private bool CanLaunchWebBrowser => Environment.UserInteractive
+        && !_startupOptions.IsService
+        && (OperatingSystem.IsWindows() || OperatingSystem.IsMacOS());
+
+    /// <inheritdoc />
+    public SystemInfo GetSystemInfo(HttpRequest request)
+    {
+        return new SystemInfo
+        {
+            HasPendingRestart = _applicationHost.HasPendingRestart,
+            IsShuttingDown = _applicationLifetime.ApplicationStopping.IsCancellationRequested,
+            Version = _applicationHost.ApplicationVersionString,
+            WebSocketPortNumber = _applicationHost.HttpPort,
+            CompletedInstallations = _installationManager.CompletedInstallations.ToArray(),
+            Id = _applicationHost.SystemId,
+            ProgramDataPath = _applicationPaths.ProgramDataPath,
+            WebPath = _applicationPaths.WebPath,
+            LogPath = _applicationPaths.LogDirectoryPath,
+            ItemsByNamePath = _applicationPaths.InternalMetadataPath,
+            InternalMetadataPath = _applicationPaths.InternalMetadataPath,
+            CachePath = _applicationPaths.CachePath,
+            CanLaunchWebBrowser = CanLaunchWebBrowser,
+            TranscodingTempPath = _configurationManager.GetTranscodePath(),
+            ServerName = _applicationHost.FriendlyName,
+            LocalAddress = _applicationHost.GetSmartApiUrl(request),
+            SupportsLibraryMonitor = true,
+            PackageName = _startupOptions.PackageName
+        };
+    }
+
+    /// <inheritdoc />
+    public PublicSystemInfo GetPublicSystemInfo(HttpRequest request)
+    {
+        return new PublicSystemInfo
+        {
+            Version = _applicationHost.ApplicationVersionString,
+            ProductName = _applicationHost.Name,
+            Id = _applicationHost.SystemId,
+            ServerName = _applicationHost.FriendlyName,
+            LocalAddress = _applicationHost.GetSmartApiUrl(request),
+            StartupWizardCompleted = _configurationManager.CommonConfiguration.IsStartupWizardCompleted
+        };
+    }
+
+    /// <inheritdoc />
+    public void Restart() => ShutdownInternal(true);
+
+    /// <inheritdoc />
+    public void Shutdown() => ShutdownInternal(false);
+
+    private void ShutdownInternal(bool restart)
+    {
+        Task.Run(async () =>
+        {
+            await Task.Delay(100).ConfigureAwait(false);
+            _applicationHost.ShouldRestart = restart;
+            _applicationLifetime.StopApplication();
+        });
+    }
+}

+ 22 - 25
Jellyfin.Api/Controllers/SystemController.cs

@@ -10,7 +10,6 @@ using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller;
-using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Net;
 using MediaBrowser.Model.Net;
 using MediaBrowser.Model.System;
 using MediaBrowser.Model.System;
@@ -26,32 +25,36 @@ namespace Jellyfin.Api.Controllers;
 /// </summary>
 /// </summary>
 public class SystemController : BaseJellyfinApiController
 public class SystemController : BaseJellyfinApiController
 {
 {
+    private readonly ILogger<SystemController> _logger;
     private readonly IServerApplicationHost _appHost;
     private readonly IServerApplicationHost _appHost;
     private readonly IApplicationPaths _appPaths;
     private readonly IApplicationPaths _appPaths;
     private readonly IFileSystem _fileSystem;
     private readonly IFileSystem _fileSystem;
-    private readonly INetworkManager _network;
-    private readonly ILogger<SystemController> _logger;
+    private readonly INetworkManager _networkManager;
+    private readonly ISystemManager _systemManager;
 
 
     /// <summary>
     /// <summary>
     /// Initializes a new instance of the <see cref="SystemController"/> class.
     /// Initializes a new instance of the <see cref="SystemController"/> class.
     /// </summary>
     /// </summary>
-    /// <param name="serverConfigurationManager">Instance of <see cref="IServerConfigurationManager"/> interface.</param>
+    /// <param name="logger">Instance of <see cref="ILogger{SystemController}"/> interface.</param>
+    /// <param name="appPaths">Instance of <see cref="IServerApplicationPaths"/> interface.</param>
     /// <param name="appHost">Instance of <see cref="IServerApplicationHost"/> interface.</param>
     /// <param name="appHost">Instance of <see cref="IServerApplicationHost"/> interface.</param>
     /// <param name="fileSystem">Instance of <see cref="IFileSystem"/> interface.</param>
     /// <param name="fileSystem">Instance of <see cref="IFileSystem"/> interface.</param>
-    /// <param name="network">Instance of <see cref="INetworkManager"/> interface.</param>
-    /// <param name="logger">Instance of <see cref="ILogger{SystemController}"/> interface.</param>
+    /// <param name="networkManager">Instance of <see cref="INetworkManager"/> interface.</param>
+    /// <param name="systemManager">Instance of <see cref="ISystemManager"/> interface.</param>
     public SystemController(
     public SystemController(
-        IServerConfigurationManager serverConfigurationManager,
+        ILogger<SystemController> logger,
         IServerApplicationHost appHost,
         IServerApplicationHost appHost,
+        IServerApplicationPaths appPaths,
         IFileSystem fileSystem,
         IFileSystem fileSystem,
-        INetworkManager network,
-        ILogger<SystemController> logger)
+        INetworkManager networkManager,
+        ISystemManager systemManager)
     {
     {
-        _appPaths = serverConfigurationManager.ApplicationPaths;
+        _logger = logger;
         _appHost = appHost;
         _appHost = appHost;
+        _appPaths = appPaths;
         _fileSystem = fileSystem;
         _fileSystem = fileSystem;
-        _network = network;
-        _logger = logger;
+        _networkManager = networkManager;
+        _systemManager = systemManager;
     }
     }
 
 
     /// <summary>
     /// <summary>
@@ -65,9 +68,7 @@ public class SystemController : BaseJellyfinApiController
     [ProducesResponseType(StatusCodes.Status200OK)]
     [ProducesResponseType(StatusCodes.Status200OK)]
     [ProducesResponseType(StatusCodes.Status403Forbidden)]
     [ProducesResponseType(StatusCodes.Status403Forbidden)]
     public ActionResult<SystemInfo> GetSystemInfo()
     public ActionResult<SystemInfo> GetSystemInfo()
-    {
-        return _appHost.GetSystemInfo(Request);
-    }
+        => _systemManager.GetSystemInfo(Request);
 
 
     /// <summary>
     /// <summary>
     /// Gets public information about the server.
     /// Gets public information about the server.
@@ -77,9 +78,7 @@ public class SystemController : BaseJellyfinApiController
     [HttpGet("Info/Public")]
     [HttpGet("Info/Public")]
     [ProducesResponseType(StatusCodes.Status200OK)]
     [ProducesResponseType(StatusCodes.Status200OK)]
     public ActionResult<PublicSystemInfo> GetPublicSystemInfo()
     public ActionResult<PublicSystemInfo> GetPublicSystemInfo()
-    {
-        return _appHost.GetPublicSystemInfo(Request);
-    }
+        => _systemManager.GetPublicSystemInfo(Request);
 
 
     /// <summary>
     /// <summary>
     /// Pings the system.
     /// Pings the system.
@@ -90,9 +89,7 @@ public class SystemController : BaseJellyfinApiController
     [HttpPost("Ping", Name = "PostPingSystem")]
     [HttpPost("Ping", Name = "PostPingSystem")]
     [ProducesResponseType(StatusCodes.Status200OK)]
     [ProducesResponseType(StatusCodes.Status200OK)]
     public ActionResult<string> PingSystem()
     public ActionResult<string> PingSystem()
-    {
-        return _appHost.Name;
-    }
+        => _appHost.Name;
 
 
     /// <summary>
     /// <summary>
     /// Restarts the application.
     /// Restarts the application.
@@ -106,7 +103,7 @@ public class SystemController : BaseJellyfinApiController
     [ProducesResponseType(StatusCodes.Status403Forbidden)]
     [ProducesResponseType(StatusCodes.Status403Forbidden)]
     public ActionResult RestartApplication()
     public ActionResult RestartApplication()
     {
     {
-        _appHost.Restart();
+        _systemManager.Restart();
         return NoContent();
         return NoContent();
     }
     }
 
 
@@ -122,7 +119,7 @@ public class SystemController : BaseJellyfinApiController
     [ProducesResponseType(StatusCodes.Status403Forbidden)]
     [ProducesResponseType(StatusCodes.Status403Forbidden)]
     public ActionResult ShutdownApplication()
     public ActionResult ShutdownApplication()
     {
     {
-        _appHost.Shutdown();
+        _systemManager.Shutdown();
         return NoContent();
         return NoContent();
     }
     }
 
 
@@ -180,7 +177,7 @@ public class SystemController : BaseJellyfinApiController
         return new EndPointInfo
         return new EndPointInfo
         {
         {
             IsLocal = HttpContext.IsLocal(),
             IsLocal = HttpContext.IsLocal(),
-            IsInNetwork = _network.IsInLocalNetwork(HttpContext.GetNormalizedRemoteIP())
+            IsInNetwork = _networkManager.IsInLocalNetwork(HttpContext.GetNormalizedRemoteIP())
         };
         };
     }
     }
 
 
@@ -218,7 +215,7 @@ public class SystemController : BaseJellyfinApiController
     [ProducesResponseType(StatusCodes.Status200OK)]
     [ProducesResponseType(StatusCodes.Status200OK)]
     public ActionResult<IEnumerable<WakeOnLanInfo>> GetWakeOnLanInfo()
     public ActionResult<IEnumerable<WakeOnLanInfo>> GetWakeOnLanInfo()
     {
     {
-        var result = _network.GetMacAddresses()
+        var result = _networkManager.GetMacAddresses()
             .Select(i => new WakeOnLanInfo(i));
             .Select(i => new WakeOnLanInfo(i));
         return Ok(result);
         return Ok(result);
     }
     }

+ 4 - 20
MediaBrowser.Common/IApplicationHost.cs

@@ -35,21 +35,15 @@ namespace MediaBrowser.Common
         string SystemId { get; }
         string SystemId { get; }
 
 
         /// <summary>
         /// <summary>
-        /// Gets a value indicating whether this instance has pending kernel reload.
+        /// Gets a value indicating whether this instance has pending changes requiring a restart.
         /// </summary>
         /// </summary>
-        /// <value><c>true</c> if this instance has pending kernel reload; otherwise, <c>false</c>.</value>
+        /// <value><c>true</c> if this instance has a pending restart; otherwise, <c>false</c>.</value>
         bool HasPendingRestart { get; }
         bool HasPendingRestart { get; }
 
 
         /// <summary>
         /// <summary>
-        /// Gets a value indicating whether this instance is currently shutting down.
+        /// Gets or sets a value indicating whether the application should restart.
         /// </summary>
         /// </summary>
-        /// <value><c>true</c> if this instance is shutting down; otherwise, <c>false</c>.</value>
-        bool IsShuttingDown { get; }
-
-        /// <summary>
-        /// Gets a value indicating whether the application should restart.
-        /// </summary>
-        bool ShouldRestart { get; }
+        bool ShouldRestart { get; set; }
 
 
         /// <summary>
         /// <summary>
         /// Gets the application version.
         /// Gets the application version.
@@ -91,11 +85,6 @@ namespace MediaBrowser.Common
         /// </summary>
         /// </summary>
         void NotifyPendingRestart();
         void NotifyPendingRestart();
 
 
-        /// <summary>
-        /// Restarts this instance.
-        /// </summary>
-        void Restart();
-
         /// <summary>
         /// <summary>
         /// Gets the exports.
         /// Gets the exports.
         /// </summary>
         /// </summary>
@@ -127,11 +116,6 @@ namespace MediaBrowser.Common
         /// <returns>``0.</returns>
         /// <returns>``0.</returns>
         T Resolve<T>();
         T Resolve<T>();
 
 
-        /// <summary>
-        /// Shuts down.
-        /// </summary>
-        void Shutdown();
-
         /// <summary>
         /// <summary>
         /// Initializes this instance.
         /// Initializes this instance.
         /// </summary>
         /// </summary>

+ 0 - 12
MediaBrowser.Controller/IServerApplicationHost.cs

@@ -4,7 +4,6 @@
 
 
 using System.Net;
 using System.Net;
 using MediaBrowser.Common;
 using MediaBrowser.Common;
-using MediaBrowser.Model.System;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http;
 
 
 namespace MediaBrowser.Controller
 namespace MediaBrowser.Controller
@@ -16,8 +15,6 @@ namespace MediaBrowser.Controller
     {
     {
         bool CoreStartupHasCompleted { get; }
         bool CoreStartupHasCompleted { get; }
 
 
-        bool CanLaunchWebBrowser { get; }
-
         /// <summary>
         /// <summary>
         /// Gets the HTTP server port.
         /// Gets the HTTP server port.
         /// </summary>
         /// </summary>
@@ -41,15 +38,6 @@ namespace MediaBrowser.Controller
         /// <value>The name of the friendly.</value>
         /// <value>The name of the friendly.</value>
         string FriendlyName { get; }
         string FriendlyName { get; }
 
 
-        /// <summary>
-        /// Gets the system info.
-        /// </summary>
-        /// <param name="request">The HTTP request.</param>
-        /// <returns>SystemInfo.</returns>
-        SystemInfo GetSystemInfo(HttpRequest request);
-
-        PublicSystemInfo GetPublicSystemInfo(HttpRequest request);
-
         /// <summary>
         /// <summary>
         /// Gets a URL specific for the request.
         /// Gets a URL specific for the request.
         /// </summary>
         /// </summary>

+ 34 - 0
MediaBrowser.Controller/ISystemManager.cs

@@ -0,0 +1,34 @@
+using MediaBrowser.Model.System;
+using Microsoft.AspNetCore.Http;
+
+namespace MediaBrowser.Controller;
+
+/// <summary>
+/// A service for managing the application instance.
+/// </summary>
+public interface ISystemManager
+{
+    /// <summary>
+    /// Gets the system info.
+    /// </summary>
+    /// <param name="request">The HTTP request.</param>
+    /// <returns>The <see cref="SystemInfo"/>.</returns>
+    SystemInfo GetSystemInfo(HttpRequest request);
+
+    /// <summary>
+    /// Gets the public system info.
+    /// </summary>
+    /// <param name="request">The HTTP request.</param>
+    /// <returns>The <see cref="PublicSystemInfo"/>.</returns>
+    PublicSystemInfo GetPublicSystemInfo(HttpRequest request);
+
+    /// <summary>
+    /// Starts the application restart process.
+    /// </summary>
+    void Restart();
+
+    /// <summary>
+    /// Starts the application shutdown process.
+    /// </summary>
+    void Shutdown();
+}