using System; using System.Linq; using System.Threading; using MediaBrowser.Model.Tasks; using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.ScheduledTasks { /// /// Represents a task trigger that runs repeatedly on an interval. /// public class IntervalTrigger : ITaskTrigger { private DateTime _lastStartDate; /// /// Occurs when [triggered]. /// public event EventHandler Triggered; /// /// Gets or sets the interval. /// /// The interval. public TimeSpan Interval { get; set; } /// /// Gets or sets the options of this task. /// public TaskOptions TaskOptions { get; set; } /// /// Gets or sets the timer. /// /// The timer. private Timer Timer { get; set; } /// /// Stars waiting for the trigger action. /// /// The last result. /// The logger. /// The name of the task. /// if set to true [is application startup]. public void Start(TaskResult lastResult, ILogger logger, string taskName, bool isApplicationStartup) { DisposeTimer(); DateTime triggerDate; if (lastResult == null) { // Task has never been completed before triggerDate = DateTime.UtcNow.AddHours(1); } else { triggerDate = new[] { lastResult.EndTimeUtc, _lastStartDate }.Max().Add(Interval); } if (DateTime.UtcNow > triggerDate) { triggerDate = DateTime.UtcNow.AddMinutes(1); } var dueTime = triggerDate - DateTime.UtcNow; var maxDueTime = TimeSpan.FromDays(7); if (dueTime > maxDueTime) { dueTime = maxDueTime; } Timer = new Timer(state => OnTriggered(), null, dueTime, TimeSpan.FromMilliseconds(-1)); } /// /// Stops waiting for the trigger action. /// public void Stop() { DisposeTimer(); } /// /// Disposes the timer. /// private void DisposeTimer() { if (Timer != null) { Timer.Dispose(); } } /// /// Called when [triggered]. /// private void OnTriggered() { DisposeTimer(); if (Triggered != null) { _lastStartDate = DateTime.UtcNow; Triggered(this, EventArgs.Empty); } } } }