Gracefully exit on restart instead of forcibly killing it

This commit is contained in:
Mark McDowall 2014-03-09 22:35:50 -07:00
parent ce13be3d43
commit c2087af8c9
13 changed files with 92 additions and 22 deletions

View File

@ -295,6 +295,14 @@ namespace Microsoft.AspNet.SignalR.Messaging
Trace.TraceEvent(TraceEventType.Verbose, 0, "Dispoing the broker");
//Check if OS is not Windows and exit
var platform = (int)Environment.OSVersion.Platform;
if ((platform == 4) || (platform == 6) || (platform == 128))
{
return;
}
// Wait for all threads to stop working
WaitForDrain();

View File

@ -14,6 +14,7 @@ namespace NzbDrone.Api.Config
public String Password { get; set; }
public String LogLevel { get; set; }
public String Branch { get; set; }
public Boolean AutoUpdate { get; set; }
public String ApiKey { get; set; }
public Boolean Torrent { get; set; }
public String SslCertHash { get; set; }

View File

@ -16,6 +16,7 @@ namespace NzbDrone.Common.EnvironmentInfo
bool IsWindowsService { get; }
bool IsConsole { get; }
bool IsRunning { get; set; }
bool RestartPending { get; set; }
string ExecutingApplication { get; }
}
@ -83,6 +84,7 @@ namespace NzbDrone.Common.EnvironmentInfo
}
public bool IsRunning { get; set; }
public bool RestartPending { get; set; }
public string ExecutingApplication { get; private set; }
public static bool IsProduction { get; private set; }

View File

@ -18,6 +18,7 @@ namespace NzbDrone.Common.EnvironmentInfo
internal const string UNINSTALL_SERVICE = "u";
public const string HELP = "?";
public const string TERMINATE = "terminateexisting";
public const string RESTART = "restart";
public StartupContext(params string[] args)
{

View File

@ -28,6 +28,7 @@ namespace NzbDrone.Core.Configuration
string Password { get; }
string LogLevel { get; }
string Branch { get; }
bool AutoUpdate { get; }
string ApiKey { get; }
bool Torrent { get; }
string SslCertHash { get; }
@ -133,6 +134,11 @@ namespace NzbDrone.Core.Configuration
get { return GetValue("Branch", "master").ToLowerInvariant(); }
}
public bool AutoUpdate
{
get { return GetValueBoolean("AutoUpdate", false, persist: false); }
}
public string Username
{
get { return GetValue("Username", ""); }

View File

@ -48,22 +48,12 @@ namespace NzbDrone.Core.Lifecycle
{
_logger.Info("Restart requested.");
if (OsInfo.IsMono)
{
_processProvider.SpawnNewProcess(_runtimeInfo.ExecutingApplication, "--terminateexisting --nobrowser");
}
_eventAggregator.PublishEvent(new ApplicationShutdownRequested(true));
if (_runtimeInfo.IsWindowsService)
{
_serviceProvider.Restart(ServiceProvider.NZBDRONE_SERVICE_NAME);
}
else
{
_processProvider.SpawnNewProcess(_runtimeInfo.ExecutingApplication, "--terminateexisting --nobrowser");
}
}
}
}

View File

@ -55,7 +55,7 @@ namespace NzbDrone.Host
{
if (OsInfo.IsMono)
{
Console.CancelKeyPress += (sender, eventArgs) => _processProvider.Kill(_processProvider.GetCurrentProcess().Id);
Console.CancelKeyPress += (sender, eventArgs) => LogManager.Configuration = null;
}
_runtimeInfo.IsRunning = true;
@ -90,13 +90,14 @@ namespace NzbDrone.Host
public void Handle(ApplicationShutdownRequested message)
{
if (OsInfo.IsMono)
if (!_runtimeInfo.IsWindowsService)
{
_processProvider.Kill(_processProvider.GetCurrentProcess().Id);
}
if (message.Restarting)
{
_runtimeInfo.RestartPending = true;
}
if (!_runtimeInfo.IsWindowsService && !message.Restarting)
{
LogManager.Configuration = null;
Shutdown();
}
}

View File

@ -5,6 +5,7 @@ using NLog;
using NzbDrone.Common.Composition;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Common.Processes;
using NzbDrone.Common.Security;
using NzbDrone.Core.Datastore;
@ -59,6 +60,11 @@ namespace NzbDrone.Host
{
if (!IsInUtilityMode(applicationModes))
{
if (startupContext.Flags.Contains(StartupContext.RESTART))
{
Thread.Sleep(2000);
}
EnsureSingleInstance(applicationModes == ApplicationModes.Service, startupContext);
}
@ -73,12 +79,7 @@ namespace NzbDrone.Host
return;
}
var runTimeInfo = _container.Resolve<IRuntimeInfo>();
while (runTimeInfo.IsRunning)
{
Thread.Sleep(1000);
}
_container.Resolve<IWaitForExit>().Spin();
}
private static void EnsureSingleInstance(bool isService, StartupContext startupContext)

View File

@ -101,6 +101,7 @@
<Compile Include="AccessControl\FirewallAdapter.cs" />
<Compile Include="AccessControl\UrlAclAdapter.cs" />
<Compile Include="BrowserService.cs" />
<Compile Include="SpinService.cs" />
<Compile Include="SingleInstancePolicy.cs" />
<Compile Include="IUserAlert.cs" />
<Compile Include="Owin\NlogTextWriter.cs" />

View File

@ -0,0 +1,36 @@
using System.Threading;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Processes;
namespace NzbDrone.Host
{
public interface IWaitForExit
{
void Spin();
}
public class SpinService : IWaitForExit
{
private readonly IRuntimeInfo _runtimeInfo;
private readonly IProcessProvider _processProvider;
public SpinService(IRuntimeInfo runtimeInfo, IProcessProvider processProvider)
{
_runtimeInfo = runtimeInfo;
_processProvider = processProvider;
}
public void Spin()
{
while (_runtimeInfo.IsRunning)
{
Thread.Sleep(1000);
}
if (_runtimeInfo.RestartPending)
{
_processProvider.SpawnNewProcess(_runtimeInfo.ExecutingApplication, "--restart --nobrowser");
}
}
}
}

View File

@ -142,5 +142,28 @@
<input type="text" placeholder="master" name="branch"/>
</div>
</div>
{{#if_mono}}
<div class="control-group">
<label class="control-label">Auto Update</label>
<div class="controls">
<label class="checkbox toggle well">
<input type="checkbox" name="autoUpdate"/>
<p>
<span>Yes</span>
<span>No</span>
</p>
<div class="btn btn-primary slide-button"/>
</label>
<span class="help-inline-checkbox">
<i class="icon-nd-form-info" title="Use drone's built in auto update instead of package manager/manual updating"/>
</span>
</div>
</div>
{{/if_mono}}
</fieldset>
</div>

Binary file not shown.

Binary file not shown.