Restart on linux/os x working

Removed client messages for shutdown/restart since they were getting stuck
This commit is contained in:
Mark McDowall 2014-02-10 01:49:06 -08:00
parent 2d50957baa
commit d0a6daeb26
17 changed files with 100 additions and 61 deletions

View File

@ -1,11 +1,6 @@
using System; using System;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Security.AccessControl;
using System.Security.Principal;
using NLog;
using NzbDrone.Common.Disk;
using NzbDrone.Common.Instrumentation;
namespace NzbDrone.Common.EnvironmentInfo namespace NzbDrone.Common.EnvironmentInfo
{ {

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Reflection;
using System.Security.Principal; using System.Security.Principal;
using System.ServiceProcess; using System.ServiceProcess;
using NLog; using NLog;
@ -15,6 +16,7 @@ namespace NzbDrone.Common.EnvironmentInfo
bool IsWindowsService { get; } bool IsWindowsService { get; }
bool IsConsole { get; } bool IsConsole { get; }
bool IsRunning { get; set; } bool IsRunning { get; set; }
string ExecutingApplication { get; }
} }
public class RuntimeInfo : IRuntimeInfo public class RuntimeInfo : IRuntimeInfo
@ -30,6 +32,8 @@ namespace NzbDrone.Common.EnvironmentInfo
OsInfo.IsWindows && OsInfo.IsWindows &&
serviceProvider.ServiceExist(ServiceProvider.NZBDRONE_SERVICE_NAME) && serviceProvider.ServiceExist(ServiceProvider.NZBDRONE_SERVICE_NAME) &&
serviceProvider.GetStatus(ServiceProvider.NZBDRONE_SERVICE_NAME) == ServiceControllerStatus.StartPending; serviceProvider.GetStatus(ServiceProvider.NZBDRONE_SERVICE_NAME) == ServiceControllerStatus.StartPending;
ExecutingApplication = Assembly.GetEntryAssembly().Location;
} }
static RuntimeInfo() static RuntimeInfo()
@ -73,6 +77,7 @@ namespace NzbDrone.Common.EnvironmentInfo
} }
public bool IsRunning { get; set; } public bool IsRunning { get; set; }
public string ExecutingApplication { get; private set; }
public static bool IsProduction { get; private set; } public static bool IsProduction { get; private set; }

View File

@ -101,6 +101,7 @@
<Compile Include="Messaging\IEvent.cs" /> <Compile Include="Messaging\IEvent.cs" />
<Compile Include="Messaging\IMessage.cs" /> <Compile Include="Messaging\IMessage.cs" />
<Compile Include="PathEqualityComparer.cs" /> <Compile Include="PathEqualityComparer.cs" />
<Compile Include="Processes\INzbDroneProcessProvider.cs" />
<Compile Include="Processes\ProcessOutput.cs" /> <Compile Include="Processes\ProcessOutput.cs" />
<Compile Include="Serializer\IntConverter.cs" /> <Compile Include="Serializer\IntConverter.cs" />
<Compile Include="Services.cs" /> <Compile Include="Services.cs" />

View File

@ -0,0 +1,10 @@
using System.Collections.Generic;
using NzbDrone.Common.Model;
namespace NzbDrone.Common.Processes
{
public interface INzbDroneProcessProvider
{
List<ProcessInfo> GetNzbDroneProcesses();
}
}

View File

@ -4,12 +4,5 @@ namespace NzbDrone.Core.Lifecycle.Commands
{ {
public class RestartCommand : Command public class RestartCommand : Command
{ {
public override bool SendUpdatesToClient
{
get
{
return true;
}
}
} }
} }

View File

@ -4,12 +4,5 @@ namespace NzbDrone.Core.Lifecycle.Commands
{ {
public class ShutdownCommand : Command public class ShutdownCommand : Command
{ {
public override bool SendUpdatesToClient
{
get
{
return true;
}
}
} }
} }

View File

@ -1,4 +1,4 @@
using System.IO; using System;
using NLog; using NLog;
using NzbDrone.Common; using NzbDrone.Common;
using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.EnvironmentInfo;
@ -11,26 +11,23 @@ using IServiceProvider = NzbDrone.Common.IServiceProvider;
namespace NzbDrone.Core.Lifecycle namespace NzbDrone.Core.Lifecycle
{ {
public class LifestyleService: IExecute<ShutdownCommand>, IExecute<RestartCommand> public class LifecycleService: IExecute<ShutdownCommand>, IExecute<RestartCommand>
{ {
private readonly IEventAggregator _eventAggregator; private readonly IEventAggregator _eventAggregator;
private readonly IRuntimeInfo _runtimeInfo; private readonly IRuntimeInfo _runtimeInfo;
private readonly IAppFolderInfo _appFolderInfo;
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
private readonly IProcessProvider _processProvider; private readonly IProcessProvider _processProvider;
private readonly Logger _logger; private readonly Logger _logger;
public LifestyleService(IEventAggregator eventAggregator, public LifecycleService(IEventAggregator eventAggregator,
IRuntimeInfo runtimeInfo, IRuntimeInfo runtimeInfo,
IAppFolderInfo appFolderInfo,
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
IProcessProvider processProvider, IProcessProvider processProvider,
Logger logger) Logger logger)
{ {
_eventAggregator = eventAggregator; _eventAggregator = eventAggregator;
_runtimeInfo = runtimeInfo; _runtimeInfo = runtimeInfo;
_appFolderInfo = appFolderInfo;
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
_processProvider = processProvider; _processProvider = processProvider;
_logger = logger; _logger = logger;
@ -38,7 +35,7 @@ namespace NzbDrone.Core.Lifecycle
public void Execute(ShutdownCommand message) public void Execute(ShutdownCommand message)
{ {
_logger.ProgressInfo("Shutdown requested, goodbye."); _logger.Info("Shutdown requested.");
_eventAggregator.PublishEvent(new ApplicationShutdownRequested()); _eventAggregator.PublishEvent(new ApplicationShutdownRequested());
if (_runtimeInfo.IsWindowsService) if (_runtimeInfo.IsWindowsService)
@ -49,7 +46,13 @@ namespace NzbDrone.Core.Lifecycle
public void Execute(RestartCommand message) public void Execute(RestartCommand message)
{ {
_logger.ProgressInfo("Restart requested, brb."); _logger.Info("Restart requested.");
if (OsInfo.IsLinux)
{
_processProvider.SpawnNewProcess(_runtimeInfo.ExecutingApplication, "--terminateexisting --nobrowser");
}
_eventAggregator.PublishEvent(new ApplicationShutdownRequested(true)); _eventAggregator.PublishEvent(new ApplicationShutdownRequested(true));
if (_runtimeInfo.IsWindowsService) if (_runtimeInfo.IsWindowsService)
@ -59,26 +62,7 @@ namespace NzbDrone.Core.Lifecycle
else else
{ {
//TODO: move this to environment specific projects _processProvider.SpawnNewProcess(_runtimeInfo.ExecutingApplication, "--terminateexisting --nobrowser");
if (OsInfo.IsWindows)
{
if (_runtimeInfo.IsConsole)
{
//Run console with switch
var path = Path.Combine(_appFolderInfo.StartUpFolder,
ProcessProvider.NZB_DRONE_CONSOLE_PROCESS_NAME + ".exe");
_processProvider.SpawnNewProcess(path, "--terminateexisting --nobrowser");
}
else
{
var path = Path.Combine(_appFolderInfo.StartUpFolder,
ProcessProvider.NZB_DRONE_PROCESS_NAME + ".exe");
_processProvider.Start(path, "--terminateexisting --nobrowser");
}
}
} }
} }
} }

View File

@ -292,7 +292,7 @@
<Compile Include="MediaFiles\Commands\RescanSeriesCommand.cs" /> <Compile Include="MediaFiles\Commands\RescanSeriesCommand.cs" />
<Compile Include="Lifecycle\Commands\ShutdownCommand.cs" /> <Compile Include="Lifecycle\Commands\ShutdownCommand.cs" />
<Compile Include="Lifecycle\Commands\RestartCommand.cs" /> <Compile Include="Lifecycle\Commands\RestartCommand.cs" />
<Compile Include="Lifecycle\LifestyleService.cs" /> <Compile Include="Lifecycle\LifecycleService.cs" />
<Compile Include="MediaFiles\Commands\RenameFilesCommand.cs" /> <Compile Include="MediaFiles\Commands\RenameFilesCommand.cs" />
<Compile Include="MediaFiles\EpisodeFileMoveResult.cs" /> <Compile Include="MediaFiles\EpisodeFileMoveResult.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\FullSeasonSpecification.cs" /> <Compile Include="MediaFiles\EpisodeImport\Specifications\FullSeasonSpecification.cs" />

View File

@ -51,6 +51,7 @@ namespace NzbDrone.Host
catch (TerminateApplicationException e) catch (TerminateApplicationException e)
{ {
Logger.Info(e.Message); Logger.Info(e.Message);
LogManager.Configuration = null;
} }
} }

View File

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Nancy.Bootstrapper; using Nancy.Bootstrapper;
using NzbDrone.Api; using NzbDrone.Api;
using NzbDrone.Common.Composition; using NzbDrone.Common.Composition;

View File

@ -117,7 +117,7 @@
<Compile Include="AccessControl\FirewallAdapter.cs" /> <Compile Include="AccessControl\FirewallAdapter.cs" />
<Compile Include="AccessControl\UrlAclAdapter.cs" /> <Compile Include="AccessControl\UrlAclAdapter.cs" />
<Compile Include="BrowserService.cs" /> <Compile Include="BrowserService.cs" />
<Compile Include="NzbDroneProcessService.cs" /> <Compile Include="SingleInstancePolicy.cs" />
<Compile Include="IUserAlert.cs" /> <Compile Include="IUserAlert.cs" />
<Compile Include="Owin\NlogTextWriter.cs" /> <Compile Include="Owin\NlogTextWriter.cs" />
<Compile Include="Owin\OwinServiceProvider.cs" /> <Compile Include="Owin\OwinServiceProvider.cs" />
@ -195,9 +195,7 @@
<Name>NzbDrone.SignalR</Name> <Name>NzbDrone.SignalR</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup />
<Folder Include="SignalR\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup> <PropertyGroup>
<PreBuildEvent> <PreBuildEvent>

View File

@ -16,12 +16,17 @@ namespace NzbDrone.Host
{ {
private readonly IProcessProvider _processProvider; private readonly IProcessProvider _processProvider;
private readonly IBrowserService _browserService; private readonly IBrowserService _browserService;
private readonly INzbDroneProcessProvider _nzbDroneProcessProvider;
private readonly Logger _logger; private readonly Logger _logger;
public SingleInstancePolicy(IProcessProvider processProvider, IBrowserService browserService, Logger logger) public SingleInstancePolicy(IProcessProvider processProvider,
IBrowserService browserService,
INzbDroneProcessProvider nzbDroneProcessProvider,
Logger logger)
{ {
_processProvider = processProvider; _processProvider = processProvider;
_browserService = browserService; _browserService = browserService;
_nzbDroneProcessProvider = nzbDroneProcessProvider;
_logger = logger; _logger = logger;
} }
@ -51,11 +56,10 @@ namespace NzbDrone.Host
private List<int> GetOtherNzbDroneProcessIds() private List<int> GetOtherNzbDroneProcessIds()
{ {
var currentId = _processProvider.GetCurrentProcess().Id; var currentId = _processProvider.GetCurrentProcess().Id;
var consoleIds = _processProvider.FindProcessByName(ProcessProvider.NZB_DRONE_CONSOLE_PROCESS_NAME) var otherProcesses = _nzbDroneProcessProvider.GetNzbDroneProcesses()
.Select(c => c.Id); .Select(c => c.Id)
var winformIds = _processProvider.FindProcessByName(ProcessProvider.NZB_DRONE_PROCESS_NAME).Select(c => c.Id); .Except(new[] {currentId})
.ToList();
var otherProcesses = consoleIds.Union(winformIds).Except(new[] { currentId }).ToList();
if (otherProcesses.Any()) if (otherProcesses.Any())
{ {

View File

@ -70,6 +70,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="DiskProvider.cs" /> <Compile Include="DiskProvider.cs" />
<Compile Include="LinuxPermissionsException.cs" /> <Compile Include="LinuxPermissionsException.cs" />
<Compile Include="NzbDroneProcessProvider.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Common.Model;
using NzbDrone.Common.Processes;
namespace NzbDrone.Mono
{
public class NzbDroneProcessProvider : INzbDroneProcessProvider
{
private readonly IProcessProvider _processProvider;
public NzbDroneProcessProvider(IProcessProvider processProvider)
{
_processProvider = processProvider;
}
public List<ProcessInfo> GetNzbDroneProcesses()
{
var monoProcesses = _processProvider.FindProcessByName("mono");
return monoProcesses.Where(c =>
{
var processArgs = _processProvider.StartAndCapture("ps", String.Format("--pid {0} -o args=", c.Id));
return processArgs.Standard.Any(p => p.Contains(ProcessProvider.NZB_DRONE_PROCESS_NAME) ||
p.Contains(ProcessProvider.NZB_DRONE_CONSOLE_PROCESS_NAME));
}).ToList();
}
}
}

View File

@ -63,6 +63,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="DiskProvider.cs" /> <Compile Include="DiskProvider.cs" />
<Compile Include="NzbDroneProcessProvider.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -0,0 +1,25 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Common.Model;
using NzbDrone.Common.Processes;
namespace NzbDrone.Windows
{
public class NzbDroneProcessProvider : INzbDroneProcessProvider
{
private readonly IProcessProvider _processProvider;
public NzbDroneProcessProvider(IProcessProvider processProvider)
{
_processProvider = processProvider;
}
public List<ProcessInfo> GetNzbDroneProcesses()
{
var consoleProcesses = _processProvider.FindProcessByName(ProcessProvider.NZB_DRONE_CONSOLE_PROCESS_NAME);
var winformProcesses = _processProvider.FindProcessByName(ProcessProvider.NZB_DRONE_PROCESS_NAME);
return consoleProcesses.Concat(winformProcesses).ToList();
}
}
}

View File

@ -7,11 +7,9 @@
<button class="btn btn-icon-only x-shutdown" title="Shutdown" data-container="body"> <button class="btn btn-icon-only x-shutdown" title="Shutdown" data-container="body">
<i class="icon-nd-shutdown"></i> <i class="icon-nd-shutdown"></i>
</button> </button>
{{#if_windows}}
<button class="btn btn-icon-only x-restart" title="Restart" data-container="body"> <button class="btn btn-icon-only x-restart" title="Restart" data-container="body">
<i class="icon-nd-restart"></i> <i class="icon-nd-restart"></i>
</button> </button>
{{/if_windows}}
</div> </div>
</li> </li>
</ul> </ul>