diff options
| author | LukePulverenti <luke.pulverenti@gmail.com> | 2013-02-25 22:43:04 -0500 |
|---|---|---|
| committer | LukePulverenti <luke.pulverenti@gmail.com> | 2013-02-25 22:43:04 -0500 |
| commit | 2d06095447b972c8c7239277428e2c67c8b7ca86 (patch) | |
| tree | 14278bd4c0732ee962b73ff4845e5022e157a0a3 /MediaBrowser.Common/ScheduledTasks | |
| parent | 364fbb9e0c7586afa296ddd7d739df086f4c3533 (diff) | |
plugin security fixes and other abstractions
Diffstat (limited to 'MediaBrowser.Common/ScheduledTasks')
5 files changed, 97 insertions, 506 deletions
diff --git a/MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs b/MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs deleted file mode 100644 index 09ceaa9aee..0000000000 --- a/MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs +++ /dev/null @@ -1,424 +0,0 @@ -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Kernel; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Tasks; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Common.ScheduledTasks -{ - /// <summary> - /// Represents a task that can be executed at a scheduled time - /// </summary> - /// <typeparam name="TKernelType">The type of the T kernel type.</typeparam> - public abstract class BaseScheduledTask<TKernelType> : IScheduledTask - where TKernelType : class, IKernel - { - /// <summary> - /// Gets the kernel. - /// </summary> - /// <value>The kernel.</value> - protected TKernelType Kernel { get; private set; } - - /// <summary> - /// Gets the logger. - /// </summary> - /// <value>The logger.</value> - protected ILogger Logger { get; private set; } - - /// <summary> - /// Gets the task manager. - /// </summary> - /// <value>The task manager.</value> - protected ITaskManager TaskManager { get; private set; } - - /// <summary> - /// Initializes a new instance of the <see cref="BaseScheduledTask{TKernelType}" /> class. - /// </summary> - /// <param name="kernel">The kernel.</param> - /// <param name="taskManager">The task manager.</param> - /// <param name="logger">The logger.</param> - /// <exception cref="System.ArgumentNullException">kernel</exception> - protected BaseScheduledTask(TKernelType kernel, ITaskManager taskManager, ILogger logger) - { - if (kernel == null) - { - throw new ArgumentNullException("kernel"); - } - if (taskManager == null) - { - throw new ArgumentNullException("taskManager"); - } - if (logger == null) - { - throw new ArgumentNullException("logger"); - } - - Kernel = kernel; - TaskManager = taskManager; - Logger = logger; - - ReloadTriggerEvents(true); - } - - /// <summary> - /// The _last execution result - /// </summary> - private TaskResult _lastExecutionResult; - /// <summary> - /// The _last execution resultinitialized - /// </summary> - private bool _lastExecutionResultinitialized; - /// <summary> - /// The _last execution result sync lock - /// </summary> - private object _lastExecutionResultSyncLock = new object(); - /// <summary> - /// Gets the last execution result. - /// </summary> - /// <value>The last execution result.</value> - public TaskResult LastExecutionResult - { - get - { - LazyInitializer.EnsureInitialized(ref _lastExecutionResult, ref _lastExecutionResultinitialized, ref _lastExecutionResultSyncLock, () => - { - try - { - return TaskManager.GetLastExecutionResult(this); - } - catch (IOException) - { - // File doesn't exist. No biggie - return null; - } - }); - - return _lastExecutionResult; - } - private set - { - _lastExecutionResult = value; - - _lastExecutionResultinitialized = value != null; - } - } - - /// <summary> - /// Gets the current cancellation token - /// </summary> - /// <value>The current cancellation token source.</value> - private CancellationTokenSource CurrentCancellationTokenSource { get; set; } - - /// <summary> - /// Gets or sets the current execution start time. - /// </summary> - /// <value>The current execution start time.</value> - private DateTime CurrentExecutionStartTime { get; set; } - - /// <summary> - /// Gets the state. - /// </summary> - /// <value>The state.</value> - public TaskState State - { - get - { - if (CurrentCancellationTokenSource != null) - { - return CurrentCancellationTokenSource.IsCancellationRequested - ? TaskState.Cancelling - : TaskState.Running; - } - - return TaskState.Idle; - } - } - - /// <summary> - /// Gets the current progress. - /// </summary> - /// <value>The current progress.</value> - public double? CurrentProgress { get; private set; } - - /// <summary> - /// The _triggers - /// </summary> - private IEnumerable<ITaskTrigger> _triggers; - /// <summary> - /// The _triggers initialized - /// </summary> - private bool _triggersInitialized; - /// <summary> - /// The _triggers sync lock - /// </summary> - private object _triggersSyncLock = new object(); - /// <summary> - /// Gets the triggers that define when the task will run - /// </summary> - /// <value>The triggers.</value> - /// <exception cref="System.ArgumentNullException">value</exception> - public IEnumerable<ITaskTrigger> Triggers - { - get - { - LazyInitializer.EnsureInitialized(ref _triggers, ref _triggersInitialized, ref _triggersSyncLock, () => TaskManager.LoadTriggers(this)); - - return _triggers; - } - set - { - if (value == null) - { - throw new ArgumentNullException("value"); - } - - // Cleanup current triggers - if (_triggers != null) - { - DisposeTriggers(); - } - - _triggers = value.ToList(); - - _triggersInitialized = true; - - ReloadTriggerEvents(false); - - TaskManager.SaveTriggers(this, _triggers); - } - } - - /// <summary> - /// Creates the triggers that define when the task will run - /// </summary> - /// <returns>IEnumerable{BaseTaskTrigger}.</returns> - public abstract IEnumerable<ITaskTrigger> GetDefaultTriggers(); - - /// <summary> - /// Returns the task to be executed - /// </summary> - /// <param name="cancellationToken">The cancellation token.</param> - /// <param name="progress">The progress.</param> - /// <returns>Task.</returns> - protected abstract Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress); - - /// <summary> - /// Gets the name of the task - /// </summary> - /// <value>The name.</value> - public abstract string Name { get; } - - /// <summary> - /// Gets the description. - /// </summary> - /// <value>The description.</value> - public abstract string Description { get; } - - /// <summary> - /// Gets the category. - /// </summary> - /// <value>The category.</value> - public virtual string Category - { - get { return "Application"; } - } - - /// <summary> - /// The _id - /// </summary> - private Guid? _id; - - /// <summary> - /// Gets the unique id. - /// </summary> - /// <value>The unique id.</value> - public Guid Id - { - get - { - if (!_id.HasValue) - { - _id = GetType().FullName.GetMD5(); - } - - return _id.Value; - } - } - - /// <summary> - /// Reloads the trigger events. - /// </summary> - /// <param name="isApplicationStartup">if set to <c>true</c> [is application startup].</param> - private void ReloadTriggerEvents(bool isApplicationStartup) - { - foreach (var trigger in Triggers) - { - trigger.Stop(); - - trigger.Triggered -= trigger_Triggered; - trigger.Triggered += trigger_Triggered; - trigger.Start(isApplicationStartup); - } - } - - /// <summary> - /// Handles the Triggered event of the trigger control. - /// </summary> - /// <param name="sender">The source of the event.</param> - /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> - async void trigger_Triggered(object sender, EventArgs e) - { - var trigger = (ITaskTrigger)sender; - - Logger.Info("{0} fired for task: {1}", trigger.GetType().Name, Name); - - trigger.Stop(); - - TaskManager.QueueScheduledTask(this); - - await Task.Delay(1000).ConfigureAwait(false); - - trigger.Start(false); - } - - /// <summary> - /// Executes the task - /// </summary> - /// <returns>Task.</returns> - /// <exception cref="System.InvalidOperationException">Cannot execute a Task that is already running</exception> - public async Task Execute() - { - // Cancel the current execution, if any - if (CurrentCancellationTokenSource != null) - { - throw new InvalidOperationException("Cannot execute a Task that is already running"); - } - - CurrentCancellationTokenSource = new CancellationTokenSource(); - - Logger.Info("Executing {0}", Name); - - var progress = new Progress<double>(); - - progress.ProgressChanged += progress_ProgressChanged; - - TaskCompletionStatus status; - CurrentExecutionStartTime = DateTime.UtcNow; - - Kernel.TcpManager.SendWebSocketMessage("ScheduledTaskBeginExecute", Name); - - try - { - await Task.Run(async () => await ExecuteInternal(CurrentCancellationTokenSource.Token, progress).ConfigureAwait(false)).ConfigureAwait(false); - - status = TaskCompletionStatus.Completed; - } - catch (OperationCanceledException) - { - status = TaskCompletionStatus.Cancelled; - } - catch (Exception ex) - { - Logger.ErrorException("Error", ex); - - status = TaskCompletionStatus.Failed; - } - - var startTime = CurrentExecutionStartTime; - var endTime = DateTime.UtcNow; - - Kernel.TcpManager.SendWebSocketMessage("ScheduledTaskEndExecute", LastExecutionResult); - - progress.ProgressChanged -= progress_ProgressChanged; - CurrentCancellationTokenSource.Dispose(); - CurrentCancellationTokenSource = null; - CurrentProgress = null; - - TaskManager.OnTaskCompleted(this, startTime, endTime, status); - } - - /// <summary> - /// Progress_s the progress changed. - /// </summary> - /// <param name="sender">The sender.</param> - /// <param name="e">The e.</param> - void progress_ProgressChanged(object sender, double e) - { - CurrentProgress = e; - } - - /// <summary> - /// Stops the task if it is currently executing - /// </summary> - /// <exception cref="System.InvalidOperationException">Cannot cancel a Task unless it is in the Running state.</exception> - public void Cancel() - { - if (State != TaskState.Running) - { - throw new InvalidOperationException("Cannot cancel a Task unless it is in the Running state."); - } - - CancelIfRunning(); - } - - /// <summary> - /// Cancels if running. - /// </summary> - public void CancelIfRunning() - { - if (State == TaskState.Running) - { - Logger.Info("Attempting to cancel Scheduled Task {0}", Name); - CurrentCancellationTokenSource.Cancel(); - } - } - - /// <summary> - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// </summary> - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// <summary> - /// Releases unmanaged and - optionally - managed resources. - /// </summary> - /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> - protected virtual void Dispose(bool dispose) - { - if (dispose) - { - DisposeTriggers(); - - if (State == TaskState.Running) - { - TaskManager.OnTaskCompleted(this, CurrentExecutionStartTime, DateTime.UtcNow, TaskCompletionStatus.Aborted); - } - - if (CurrentCancellationTokenSource != null) - { - CurrentCancellationTokenSource.Dispose(); - } - } - } - - /// <summary> - /// Disposes each trigger - /// </summary> - private void DisposeTriggers() - { - foreach (var trigger in Triggers) - { - trigger.Triggered -= trigger_Triggered; - trigger.Stop(); - } - } - } -} diff --git a/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs b/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs index 6f3a3857fe..351e96c7d5 100644 --- a/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs +++ b/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs @@ -1,40 +1,16 @@ -using MediaBrowser.Model.Tasks; -using System; +using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Common.ScheduledTasks { /// <summary> - /// Interface IScheduledTask + /// Interface IScheduledTaskWorker /// </summary> - public interface IScheduledTask : IDisposable + public interface IScheduledTask { /// <summary> - /// Gets the triggers. - /// </summary> - /// <value>The triggers.</value> - IEnumerable<ITaskTrigger> Triggers { get; set; } - - /// <summary> - /// Gets the last execution result. - /// </summary> - /// <value>The last execution result.</value> - TaskResult LastExecutionResult { get; } - - /// <summary> - /// Gets the state. - /// </summary> - /// <value>The state.</value> - TaskState State { get; } - - /// <summary> - /// Gets the current progress. - /// </summary> - /// <value>The current progress.</value> - double? CurrentProgress { get; } - - /// <summary> /// Gets the name of the task /// </summary> /// <value>The name.</value> @@ -53,28 +29,12 @@ namespace MediaBrowser.Common.ScheduledTasks string Category { get; } /// <summary> - /// Gets the unique id. - /// </summary> - /// <value>The unique id.</value> - Guid Id { get; } - - /// <summary> /// Executes the task /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <param name="progress">The progress.</param> /// <returns>Task.</returns> - /// <exception cref="System.InvalidOperationException">Cannot execute a Task that is already running</exception> - Task Execute(); - - /// <summary> - /// Stops the task if it is currently executing - /// </summary> - /// <exception cref="System.InvalidOperationException">Cannot cancel a Task unless it is in the Running state.</exception> - void Cancel(); - - /// <summary> - /// Cancels if running. - /// </summary> - void CancelIfRunning(); + Task Execute(CancellationToken cancellationToken, IProgress<double> progress); /// <summary> /// Gets the default triggers. @@ -82,4 +42,4 @@ namespace MediaBrowser.Common.ScheduledTasks /// <returns>IEnumerable{BaseTaskTrigger}.</returns> IEnumerable<ITaskTrigger> GetDefaultTriggers(); } -}
\ No newline at end of file +} diff --git a/MediaBrowser.Common/ScheduledTasks/IScheduledTaskWorker.cs b/MediaBrowser.Common/ScheduledTasks/IScheduledTaskWorker.cs new file mode 100644 index 0000000000..31cb4bcb89 --- /dev/null +++ b/MediaBrowser.Common/ScheduledTasks/IScheduledTaskWorker.cs @@ -0,0 +1,86 @@ +using MediaBrowser.Model.Tasks; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace MediaBrowser.Common.ScheduledTasks +{ + /// <summary> + /// Interface IScheduledTaskWorker + /// </summary> + public interface IScheduledTaskWorker : IDisposable + { + /// <summary> + /// Gets or sets the scheduled task. + /// </summary> + /// <value>The scheduled task.</value> + IScheduledTask ScheduledTask { get; } + + /// <summary> + /// Gets the last execution result. + /// </summary> + /// <value>The last execution result.</value> + TaskResult LastExecutionResult { get; } + + /// <summary> + /// Gets the name. + /// </summary> + /// <value>The name.</value> + string Name { get; } + + /// <summary> + /// Gets the description. + /// </summary> + /// <value>The description.</value> + string Description { get; } + + /// <summary> + /// Gets the category. + /// </summary> + /// <value>The category.</value> + string Category { get; } + + /// <summary> + /// Gets the state. + /// </summary> + /// <value>The state.</value> + TaskState State { get; } + + /// <summary> + /// Gets the current progress. + /// </summary> + /// <value>The current progress.</value> + double? CurrentProgress { get; } + + /// <summary> + /// Gets the triggers that define when the task will run + /// </summary> + /// <value>The triggers.</value> + /// <exception cref="System.ArgumentNullException">value</exception> + IEnumerable<ITaskTrigger> Triggers { get; set; } + + /// <summary> + /// Gets the unique id. + /// </summary> + /// <value>The unique id.</value> + Guid Id { get; } + + /// <summary> + /// Executes the task + /// </summary> + /// <returns>Task.</returns> + /// <exception cref="System.InvalidOperationException">Cannot execute a Task that is already running</exception> + Task Execute(); + + /// <summary> + /// Stops the task if it is currently executing + /// </summary> + /// <exception cref="System.InvalidOperationException">Cannot cancel a Task unless it is in the Running state.</exception> + void Cancel(); + + /// <summary> + /// Cancels if running. + /// </summary> + void CancelIfRunning(); + } +}
\ No newline at end of file diff --git a/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs b/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs index 42d7020e60..d06f1f1946 100644 --- a/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs +++ b/MediaBrowser.Common/ScheduledTasks/ITaskManager.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Model.Tasks; -using System; +using System; using System.Collections.Generic; namespace MediaBrowser.Common.ScheduledTasks @@ -10,7 +9,7 @@ namespace MediaBrowser.Common.ScheduledTasks /// Gets the list of Scheduled Tasks /// </summary> /// <value>The scheduled tasks.</value> - IScheduledTask[] ScheduledTasks { get; } + IScheduledTaskWorker[] ScheduledTasks { get; } /// <summary> /// Cancels if running and queue. @@ -37,35 +36,5 @@ namespace MediaBrowser.Common.ScheduledTasks /// </summary> /// <param name="tasks">The tasks.</param> void AddTasks(IEnumerable<IScheduledTask> tasks); - - /// <summary> - /// Called when [task completed]. - /// </summary> - /// <param name="task">The task.</param> - /// <param name="startTime">The start time.</param> - /// <param name="endTime">The end time.</param> - /// <param name="status">The status.</param> - void OnTaskCompleted(IScheduledTask task, DateTime startTime, DateTime endTime, TaskCompletionStatus status); - - /// <summary> - /// Gets the last execution result. - /// </summary> - /// <param name="task">The task.</param> - /// <returns>TaskResult.</returns> - TaskResult GetLastExecutionResult(IScheduledTask task); - - /// <summary> - /// Loads the triggers. - /// </summary> - /// <param name="task">The task.</param> - /// <returns>IEnumerable{BaseTaskTrigger}.</returns> - IEnumerable<ITaskTrigger> LoadTriggers(IScheduledTask task); - - /// <summary> - /// Saves the triggers. - /// </summary> - /// <param name="task">The task.</param> - /// <param name="triggers">The triggers.</param> - void SaveTriggers(IScheduledTask task, IEnumerable<ITaskTrigger> triggers); } }
\ No newline at end of file diff --git a/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs b/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs index 2c3d21a4b0..ebfc94591e 100644 --- a/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs +++ b/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Common.ScheduledTasks /// </summary> /// <param name="task">The task.</param> /// <returns>TaskInfo.</returns> - public static TaskInfo GetTaskInfo(IScheduledTask task) + public static TaskInfo GetTaskInfo(IScheduledTaskWorker task) { return new TaskInfo { |
