Gracefully exit on restart instead of forcibly killing it

pull/4/head
Mark McDowall 10 years ago
parent ce13be3d43
commit c2087af8c9

@ -295,6 +295,14 @@ namespace Microsoft.AspNet.SignalR.Messaging
Trace.TraceEvent(TraceEventType.Verbose, 0, "Dispoing the broker"); 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 // Wait for all threads to stop working
WaitForDrain(); WaitForDrain();

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

@ -16,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; }
bool RestartPending { get; set; }
string ExecutingApplication { get; } string ExecutingApplication { get; }
} }
@ -83,6 +84,7 @@ namespace NzbDrone.Common.EnvironmentInfo
} }
public bool IsRunning { get; set; } public bool IsRunning { get; set; }
public bool RestartPending { get; set; }
public string ExecutingApplication { get; private set; } public string ExecutingApplication { get; private set; }
public static bool IsProduction { get; private set; } public static bool IsProduction { get; private set; }

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

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

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

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

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

@ -101,6 +101,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="SpinService.cs" />
<Compile Include="SingleInstancePolicy.cs" /> <Compile Include="SingleInstancePolicy.cs" />
<Compile Include="IUserAlert.cs" /> <Compile Include="IUserAlert.cs" />
<Compile Include="Owin\NlogTextWriter.cs" /> <Compile Include="Owin\NlogTextWriter.cs" />

@ -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");
}
}
}
}

@ -142,5 +142,28 @@
<input type="text" placeholder="master" name="branch"/> <input type="text" placeholder="master" name="branch"/>
</div> </div>
</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> </fieldset>
</div> </div>

Binary file not shown.

Binary file not shown.
Loading…
Cancel
Save