using System; using System.Threading; using System.Threading.Tasks; using NLog; using NzbDrone.Core.Lifecycle; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; using Timer = System.Timers.Timer; using NzbDrone.Common.TPL; namespace NzbDrone.Core.Jobs { public class Scheduler : IHandle, IHandle { private readonly ITaskManager _taskManager; private readonly ICommandExecutor _commandExecutor; private readonly Logger _logger; private static readonly Timer Timer = new Timer(); private static CancellationTokenSource _cancellationTokenSource; public Scheduler(ITaskManager taskManager, ICommandExecutor commandExecutor, Logger logger) { _taskManager = taskManager; _commandExecutor = commandExecutor; _logger = logger; } private void ExecuteCommands() { try { Timer.Enabled = false; var tasks = _taskManager.GetPending(); _logger.Trace("Pending Tasks: {0}", tasks.Count); foreach (var task in tasks) { _cancellationTokenSource.Token.ThrowIfCancellationRequested(); try { _commandExecutor.PublishCommand(task.TypeName, task.LastExecution); } catch (Exception e) { _logger.ErrorException("Error occurred while executing task " + task.TypeName, e); } } } finally { if (!_cancellationTokenSource.IsCancellationRequested) { Timer.Enabled = true; } } } public void Handle(ApplicationStartedEvent message) { _cancellationTokenSource = new CancellationTokenSource(); Timer.Interval = 1000 * 30; Timer.Elapsed += (o, args) => Task.Factory.StartNew(ExecuteCommands, _cancellationTokenSource.Token) .LogExceptions(); Timer.Start(); } public void Handle(ApplicationShutdownRequested message) { _logger.Info("Shutting down scheduler"); _cancellationTokenSource.Cancel(true); Timer.Stop(); } } }