mirror of
https://github.com/Sonarr/Sonarr.git
synced 2025-03-05 15:15:59 +02:00
Shutdown! Restart working for services
This commit is contained in:
parent
119a4ff39c
commit
f69bb79077
@ -13,11 +13,14 @@ namespace NzbDrone.Common.EnvironmentInfo
|
||||
bool IsUserInteractive { get; }
|
||||
bool IsAdmin { get; }
|
||||
bool IsWindowsService { get; }
|
||||
bool IsConsole { get; }
|
||||
bool IsRunning { get; set; }
|
||||
}
|
||||
|
||||
public class RuntimeInfo : IRuntimeInfo
|
||||
{
|
||||
private readonly Logger _logger;
|
||||
private static readonly string ProcessName = Process.GetCurrentProcess().ProcessName.ToLower();
|
||||
|
||||
public RuntimeInfo(Logger logger, IServiceProvider serviceProvider)
|
||||
{
|
||||
@ -29,16 +32,16 @@ namespace NzbDrone.Common.EnvironmentInfo
|
||||
serviceProvider.GetStatus(ServiceProvider.NZBDRONE_SERVICE_NAME) == ServiceControllerStatus.StartPending;
|
||||
}
|
||||
|
||||
public bool IsUserInteractive
|
||||
{
|
||||
get { return Environment.UserInteractive; }
|
||||
}
|
||||
|
||||
static RuntimeInfo()
|
||||
{
|
||||
IsProduction = InternalIsProduction();
|
||||
}
|
||||
|
||||
public bool IsUserInteractive
|
||||
{
|
||||
get { return Environment.UserInteractive; }
|
||||
}
|
||||
|
||||
public bool IsAdmin
|
||||
{
|
||||
get
|
||||
@ -58,7 +61,18 @@ namespace NzbDrone.Common.EnvironmentInfo
|
||||
|
||||
public bool IsWindowsService { get; private set; }
|
||||
|
||||
private static readonly string ProcessName = Process.GetCurrentProcess().ProcessName.ToLower();
|
||||
public bool IsConsole
|
||||
{
|
||||
get
|
||||
{
|
||||
return (OsInfo.IsWindows &&
|
||||
IsUserInteractive &&
|
||||
ProcessName.Equals("NzbDrone.Console.exe", StringComparison.InvariantCultureIgnoreCase)) ||
|
||||
OsInfo.IsLinux;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsRunning { get; set; }
|
||||
|
||||
public static bool IsProduction { get; private set; }
|
||||
|
||||
|
@ -5,6 +5,7 @@ using NLog;
|
||||
using NLog.Config;
|
||||
using NLog.Targets;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Processes;
|
||||
|
||||
namespace NzbDrone.Common.Instrumentation
|
||||
{
|
||||
@ -30,7 +31,7 @@ namespace NzbDrone.Common.Instrumentation
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inConsole && (OsInfo.IsLinux || new RuntimeInfo(null, new ServiceProvider()).IsUserInteractive))
|
||||
if (inConsole && (OsInfo.IsLinux || new RuntimeInfo(null, new ServiceProvider(new ProcessProvider())).IsUserInteractive))
|
||||
{
|
||||
RegisterConsole();
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ using System.Linq;
|
||||
using System.ServiceProcess;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Instrumentation;
|
||||
using NzbDrone.Common.Processes;
|
||||
|
||||
namespace NzbDrone.Common
|
||||
{
|
||||
@ -20,14 +21,22 @@ namespace NzbDrone.Common
|
||||
void Stop(string serviceName);
|
||||
void Start(string serviceName);
|
||||
ServiceControllerStatus GetStatus(string serviceName);
|
||||
void Restart(string serviceName);
|
||||
}
|
||||
|
||||
public class ServiceProvider : IServiceProvider
|
||||
{
|
||||
public const string NZBDRONE_SERVICE_NAME = "NzbDrone";
|
||||
|
||||
private readonly IProcessProvider _processProvider;
|
||||
|
||||
private static readonly Logger Logger = NzbDroneLogger.GetLogger();
|
||||
|
||||
public ServiceProvider(IProcessProvider processProvider)
|
||||
{
|
||||
_processProvider = processProvider;
|
||||
}
|
||||
|
||||
public virtual bool ServiceExist(string name)
|
||||
{
|
||||
Logger.Debug("Checking if service {0} exists.", name);
|
||||
@ -173,5 +182,12 @@ namespace NzbDrone.Common
|
||||
Logger.Error("Service start request has timed out. {0}", service.Status);
|
||||
}
|
||||
}
|
||||
|
||||
public void Restart(string serviceName)
|
||||
{
|
||||
var args = String.Format("/C net.exe stop \"{0}\" && net.exe start \"{0}\"", serviceName);
|
||||
|
||||
_processProvider.Start("cmd.exe", args);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
using NzbDrone.Common.Messaging;
|
||||
|
||||
namespace NzbDrone.Core.Lifecycle
|
||||
{
|
||||
public class ApplicationRestartRequested : IEvent
|
||||
{
|
||||
|
||||
}
|
||||
}
|
8
src/NzbDrone.Core/Lifecycle/Commands/RestartCommand.cs
Normal file
8
src/NzbDrone.Core/Lifecycle/Commands/RestartCommand.cs
Normal file
@ -0,0 +1,8 @@
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
|
||||
namespace NzbDrone.Core.Lifecycle.Commands
|
||||
{
|
||||
public class RestartCommand : Command
|
||||
{
|
||||
}
|
||||
}
|
8
src/NzbDrone.Core/Lifecycle/Commands/ShutdownCommand.cs
Normal file
8
src/NzbDrone.Core/Lifecycle/Commands/ShutdownCommand.cs
Normal file
@ -0,0 +1,8 @@
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
|
||||
namespace NzbDrone.Core.Lifecycle.Commands
|
||||
{
|
||||
public class ShutdownCommand : Command
|
||||
{
|
||||
}
|
||||
}
|
53
src/NzbDrone.Core/Lifecycle/LifestyleService.cs
Normal file
53
src/NzbDrone.Core/Lifecycle/LifestyleService.cs
Normal file
@ -0,0 +1,53 @@
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Processes;
|
||||
using NzbDrone.Core.Lifecycle.Commands;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using IServiceProvider = NzbDrone.Common.IServiceProvider;
|
||||
|
||||
namespace NzbDrone.Core.Lifecycle
|
||||
{
|
||||
public class LifestyleService: IExecute<ShutdownCommand>, IExecute<RestartCommand>
|
||||
{
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly IRuntimeInfo _runtimeInfo;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IProcessProvider _processProvider;
|
||||
|
||||
|
||||
public LifestyleService(IEventAggregator eventAggregator,
|
||||
IRuntimeInfo runtimeInfo,
|
||||
IServiceProvider serviceProvider,
|
||||
IProcessProvider processProvider)
|
||||
{
|
||||
_eventAggregator = eventAggregator;
|
||||
_runtimeInfo = runtimeInfo;
|
||||
_serviceProvider = serviceProvider;
|
||||
_processProvider = processProvider;
|
||||
}
|
||||
|
||||
public void Execute(ShutdownCommand message)
|
||||
{
|
||||
if (_runtimeInfo.IsWindowsService)
|
||||
{
|
||||
_serviceProvider.Stop(ServiceProvider.NZBDRONE_SERVICE_NAME);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
_eventAggregator.PublishEvent(new ApplicationShutdownRequested());
|
||||
}
|
||||
}
|
||||
|
||||
public void Execute(RestartCommand message)
|
||||
{
|
||||
if (_runtimeInfo.IsWindowsService)
|
||||
{
|
||||
_serviceProvider.Restart(ServiceProvider.NZBDRONE_SERVICE_NAME);
|
||||
}
|
||||
|
||||
_eventAggregator.PublishEvent(new ApplicationRestartRequested());
|
||||
}
|
||||
}
|
||||
}
|
@ -290,6 +290,10 @@
|
||||
<Compile Include="Instrumentation\Commands\TrimLogCommand.cs" />
|
||||
<Compile Include="Instrumentation\DeleteLogFilesService.cs" />
|
||||
<Compile Include="MediaFiles\Commands\RescanSeriesCommand.cs" />
|
||||
<Compile Include="Lifecycle\Commands\ShutdownCommand.cs" />
|
||||
<Compile Include="Lifecycle\Commands\RestartCommand.cs" />
|
||||
<Compile Include="Lifecycle\ApplicationRestartRequested.cs" />
|
||||
<Compile Include="Lifecycle\LifestyleService.cs" />
|
||||
<Compile Include="MediaFiles\Commands\RenameFilesCommand.cs" />
|
||||
<Compile Include="MediaFiles\EpisodeFileMoveResult.cs" />
|
||||
<Compile Include="MediaFiles\EpisodeImport\Specifications\FullSeasonSpecification.cs" />
|
||||
|
@ -2,18 +2,19 @@
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Lifecycle;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Host.Owin;
|
||||
|
||||
namespace NzbDrone.Host
|
||||
{
|
||||
public interface INzbDroneServiceFactory
|
||||
{
|
||||
bool IsServiceStopped { get; }
|
||||
ServiceBase Build();
|
||||
void Start();
|
||||
}
|
||||
|
||||
public class NzbDroneServiceFactory : ServiceBase, INzbDroneServiceFactory
|
||||
public class NzbDroneServiceFactory : ServiceBase, INzbDroneServiceFactory, IHandle<ApplicationShutdownRequested>
|
||||
{
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IRuntimeInfo _runtimeInfo;
|
||||
@ -42,6 +43,7 @@ namespace NzbDrone.Host
|
||||
|
||||
public void Start()
|
||||
{
|
||||
_runtimeInfo.IsRunning = true;
|
||||
_hostController.StartServer();
|
||||
|
||||
if (!_startupContext.Flags.Contains(StartupContext.NO_BROWSER)
|
||||
@ -55,18 +57,28 @@ namespace NzbDrone.Host
|
||||
|
||||
protected override void OnStop()
|
||||
{
|
||||
_logger.Info("Attempting to stop application.");
|
||||
_hostController.StopServer();
|
||||
_logger.Info("Application has finished stop routine.");
|
||||
IsServiceStopped = true;
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
public bool IsServiceStopped { get; private set; }
|
||||
|
||||
public ServiceBase Build()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
private void Shutdown()
|
||||
{
|
||||
_logger.Info("Attempting to stop application.");
|
||||
_hostController.StopServer();
|
||||
_logger.Info("Application has finished stop routine.");
|
||||
_runtimeInfo.IsRunning = false;
|
||||
}
|
||||
|
||||
public void Handle(ApplicationShutdownRequested message)
|
||||
{
|
||||
if (!_runtimeInfo.IsWindowsService)
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -72,9 +72,9 @@ namespace NzbDrone.Host
|
||||
return;
|
||||
}
|
||||
|
||||
var serviceFactory = _container.Resolve<INzbDroneServiceFactory>();
|
||||
var runTimeInfo = _container.Resolve<IRuntimeInfo>();
|
||||
|
||||
while (!serviceFactory.IsServiceStopped)
|
||||
while (runTimeInfo.IsRunning)
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
|
@ -68,8 +68,16 @@ namespace NzbDrone.SysTray
|
||||
_trayIcon.Dispose();
|
||||
}
|
||||
|
||||
if (InvokeRequired)
|
||||
{
|
||||
base.Invoke(new MethodInvoker(() => Dispose(isDisposing)));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnExit(object sender, EventArgs e)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user