From fa212872ab991c646b97d72d8ba73311c316a676 Mon Sep 17 00:00:00 2001 From: Leonardo Galli Date: Mon, 19 Feb 2018 12:48:56 +0100 Subject: [PATCH] Added: Handle ctrl-c more gracefully. Finally fixes #2218 --- src/NzbDrone.Host/ApplicationServer.cs | 5 +- src/NzbDrone.Host/Bootstrap.cs | 2 + src/NzbDrone.Host/CancelHandler.cs | 67 ++++++++++++++++++++++++++ src/NzbDrone.Host/NzbDrone.Host.csproj | 1 + 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/NzbDrone.Host/CancelHandler.cs diff --git a/src/NzbDrone.Host/ApplicationServer.cs b/src/NzbDrone.Host/ApplicationServer.cs index 62803f868..5027b6be5 100644 --- a/src/NzbDrone.Host/ApplicationServer.cs +++ b/src/NzbDrone.Host/ApplicationServer.cs @@ -26,6 +26,7 @@ public class NzbDroneServiceFactory : ServiceBase, INzbDroneServiceFactory, IHan private readonly IBrowserService _browserService; private readonly IContainer _container; private readonly Logger _logger; + private CancelHandler _cancelHandler; public NzbDroneServiceFactory(IConfigFileProvider configFileProvider, IHostController hostController, @@ -53,7 +54,8 @@ public void Start() { if (OsInfo.IsNotWindows) { - Console.CancelKeyPress += (sender, eventArgs) => LogManager.Configuration = null; + //Console.CancelKeyPress += (sender, eventArgs) => eventArgs.Cancel = true; + //_cancelHandler = new CancelHandler(); } _runtimeInfo.IsRunning = true; @@ -66,6 +68,7 @@ public void Start() _browserService.LaunchWebUI(); } + _container.Resolve().PublishEvent(new ApplicationStartedEvent()); } diff --git a/src/NzbDrone.Host/Bootstrap.cs b/src/NzbDrone.Host/Bootstrap.cs index 8ffbf8b59..9f7c08b54 100644 --- a/src/NzbDrone.Host/Bootstrap.cs +++ b/src/NzbDrone.Host/Bootstrap.cs @@ -37,6 +37,8 @@ public static void Start(StartupContext startupContext, IUserAlert userAlert, Ac var appMode = GetApplicationMode(startupContext); Start(appMode, startupContext); + + _container.Resolve().Attach(); if (startCallback != null) { diff --git a/src/NzbDrone.Host/CancelHandler.cs b/src/NzbDrone.Host/CancelHandler.cs new file mode 100644 index 000000000..870edbb22 --- /dev/null +++ b/src/NzbDrone.Host/CancelHandler.cs @@ -0,0 +1,67 @@ +using System; +using NLog; +using NzbDrone.Core.Lifecycle; + +namespace Radarr.Host +{ + public interface ICancelHandler + { + void Attach(); + } + + class CancelHandler : ICancelHandler + { + private object _syncRoot; + private volatile bool _cancelInitiated; + private readonly ILifecycleService _lifecycleService; + + public CancelHandler(ILifecycleService lifecycleService) + { + _lifecycleService = lifecycleService; + } + + public void Attach() + { + Console.CancelKeyPress += HandlerCancelKeyPress; + _syncRoot = new object(); + } + + private void HandlerCancelKeyPress(object sender, ConsoleCancelEventArgs e) + { + // Tell system to ignore the Ctrl+C and not terminate. We'll do that. + e.Cancel = true; + + var shouldTerminate = false; + lock (_syncRoot) + { + shouldTerminate = _cancelInitiated; + _cancelInitiated = true; + } + + // TODO: Probably should schedule these on the threadpool. + if (shouldTerminate) + { + UngracefulShutdown(); + } + else + { + GracefulShutdown(); + } + } + + private void GracefulShutdown() + { + Console.WriteLine("Shutdown requested, press Ctrl+C again to terminate directly."); + // TODO: Sent ApplicationShutdownRequested event or something like it. + _lifecycleService.Shutdown(); + } + + private void UngracefulShutdown() + { + Console.WriteLine("Termination requested."); + // TODO: Kill it. Shutdown NLog and invoke Environment.Exit. + LogManager.Configuration = null; + Environment.Exit(0); + } + } +} diff --git a/src/NzbDrone.Host/NzbDrone.Host.csproj b/src/NzbDrone.Host/NzbDrone.Host.csproj index 97eb61d15..de791d870 100644 --- a/src/NzbDrone.Host/NzbDrone.Host.csproj +++ b/src/NzbDrone.Host/NzbDrone.Host.csproj @@ -113,6 +113,7 @@ +