|
|
|
using System;
|
|
|
|
using NLog;
|
|
|
|
using NzbDrone.Core.Lifecycle;
|
|
|
|
|
|
|
|
namespace Radarr.Host
|
|
|
|
{
|
|
|
|
public interface ICancelHandler
|
|
|
|
{
|
|
|
|
void Attach();
|
|
|
|
}
|
|
|
|
|
|
|
|
public class CancelHandler : ICancelHandler
|
|
|
|
{
|
|
|
|
private readonly ILifecycleService _lifecycleService;
|
|
|
|
private object _syncRoot;
|
|
|
|
private volatile bool _cancelInitiated;
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|