private void ProcessBroadcastTask(TaskProcessorJob job) { // Ensure cancellation has not been requested. job.ThrowIfCancellationRequested(); // Update the progress of the task in the task queue. this.TaskProcessor.UpdateTaskAsAssignedToProcessor(job); // Sanity. if (null == job.Data?.Value) { return; } // Deserialize the directive. EmailByUserPatchDirective dir = TaskQueueDirective.Parse <EmailByUserPatchDirective>(job.Data.Value); if (dir.GeneratedFromGuid != CurrentServer.ServerID) { // Debug Logging. if (this.Configuration.LoggingEnabled) { SysUtils.ReportInfoToEventLog($"Broadcast processing with task id => {job.Data.Value.Id} on server {CurrentServer.ServerID}."); } // The task was created on another server, so we should process it on this server. AddOrUpdateEmailByUserId(dir.UserAccount, dir.Email); } }
/// <summary> /// Marks any future executions of this job in this queue as cancelled. /// </summary> /// <param name="backgroundOperationName">If set, cancels only future executions for the specified background operation.</param> /// <param name="remarks">Remarks to set on the cancellation.</param> public void CancelFutureExecutions(string backgroundOperationName = null, string remarks = null) { try { // Cancel any tasks that are already scheduled. var tasksToCancel = TaskQueueAdministrator.FindTasks ( this.VaultApplication.PermanentVault, this.QueueId, t => t.Type == TaskQueueBackgroundOperation.TaskTypeId, new[] { MFTaskState.MFTaskStateWaiting, MFTaskState.MFTaskStateInProgress } ); foreach (var task in tasksToCancel.Cast <ApplicationTaskInfo>()) { var applicationTask = task.ToApplicationTask(); // Skip any that are not for this background operation. if (false == string.IsNullOrWhiteSpace(backgroundOperationName)) { var backgroundOperationDirective = TaskQueueDirective.Parse <BackgroundOperationTaskQueueDirective>(applicationTask); if (null == backgroundOperationDirective?.BackgroundOperationName) { continue; } if (!backgroundOperationDirective.BackgroundOperationName.Equals(backgroundOperationName)) { continue; } } try { // Mark each task as superseded. this.TaskProcessor.UpdateCancelledJobInTaskQueue ( applicationTask, string.Empty, remarks ); } catch (Exception e) { SysUtils.ReportErrorToEventLog ( $"Exception cancelling task {task.TaskID} of type {TaskQueueBackgroundOperation.TaskTypeId} on queue {this.QueueId} to cancel.", e ); } } } catch (Exception e) { SysUtils.ReportErrorToEventLog ( $"Exception retrieving tasks of type {TaskQueueBackgroundOperation.TaskTypeId} on queue {this.QueueId} to cancel.", e ); } }
/// <summary> /// Instantiates a background operation task queue directive that /// may include a wrapped internal directive. /// </summary> /// <param name="backgroundOperationName">The name of the background operation on which this task is run.</param> /// <param name="internalDirective">The directive - if any - to pass to the job.</param> public BackgroundOperationTaskQueueDirective ( string backgroundOperationName, TaskQueueDirective internalDirective ) { this.BackgroundOperationName = backgroundOperationName; this.InternalDirective = internalDirective; }
public void RunAtIntervals(string name, TimeSpan interval, TaskQueueDirective directive = null) { if (!BackgroundOperations.Keys.Contains(name)) { return; } BackgroundOperations[name].Operation.RunAtIntervals(interval, directive); }
public void RunOnce(string name, DateTime?runAt = null, TaskQueueDirective directive = null) { if (!BackgroundOperations.Keys.Contains(name)) { return; } BackgroundOperations[name].Operation.RunOnce(runAt, directive); }
/// <summary> /// Wraps a call to <see cref="TaskQueueDirective.Parse{T}(Common.ApplicationTaskQueue.ApplicationTask)"/> /// to extract any directive supplied to the <paramref name="job" />. /// </summary> /// <typeparam name="TDirective">The type of the directive.</typeparam> /// <param name="job">The job to retrieve the directive for.</param> /// <returns>The directive, or null if no directive passed.</returns> public static TDirective GetTaskQueueDirective <TDirective>(this TaskProcessorJob job) where TDirective : TaskQueueDirective { // Sanity. if (null == job?.Data?.Value) { return(null); } // Unwrap. return(TaskQueueDirective.Parse <TDirective>(job.Data?.Value)); }
/// <summary> /// Runs the operation at once or immediately after the current run is finished. /// </summary> /// <param name="backgroundOperationName">The name of the background operation that should be invoked when this job is run.</param> /// <param name="runAt">If specified, schedules an execution at the provided time. Otherwise schedules a call immediately.</param> /// <param name="directive">The directive - if any - to pass to the job.</param> /// <remarks>Does not remove any scheduled executions. Use <see cref="StopRunningAtIntervals"/>.</remarks> public void RunOnce ( string backgroundOperationName, DateTime?runAt = null, TaskQueueDirective directive = null ) { // Use the other overload. this.RunOnce <TaskQueueDirective> ( backgroundOperationName, runAt, directive ); }
/// <summary> /// Creates a new background operation and starts it. /// The background operation runs the given method according to the <paramref name="schedule"/>. /// </summary> /// <param name="name">The name of the operation.</param> /// <param name="schedule">The schedule that defines when the operation should run.</param> /// <param name="method">The method to invoke at given intervals.</param> /// <param name="directive">The directive to pass to the job.</param> /// <returns>A started background operation.</returns> public TaskQueueBackgroundOperation StartScheduledBackgroundOperation ( string name, Schedule schedule, Action <TaskProcessorJob, TaskQueueDirective> method, TaskQueueDirective directive = null ) { return(this.StartScheduledBackgroundOperation <TaskQueueDirective> ( name, schedule, method, directive )); }
/// <summary> /// Creates a new background operation and starts it. The background operation runs the given method at given intervals. /// </summary> /// <param name="name">The name of the operation.</param> /// <param name="interval">The target interval between method calls. If the method call takes longer than the interval, the method will be invoked immediately after the previous method call returns.</param> /// <param name="method">The method to invoke at given intervals.</param> /// <param name="directive">The directive to pass to the job.</param> /// <returns>A started background operation.</returns> public TaskQueueBackgroundOperation StartRecurringBackgroundOperation ( string name, TimeSpan interval, Action <TaskProcessorJob, TaskQueueDirective> method, TaskQueueDirective directive = null ) { return(this.StartRecurringBackgroundOperation <TaskQueueDirective> ( name, interval, method, directive )); }
/// <summary> /// Adds a task to the task queue, optionally with a directive. /// </summary> /// <typeparam name="TSettings">The settings type used by the task processor.</typeparam> /// <param name="taskProcessor">The task processor to add the task to.</param> /// <param name="taskQueue">The queue ID to add this task to.</param> /// <param name="taskType">The task type.</param> /// <param name="directive">The directive - if any - to associate with the job.</param> /// <param name="allowRetry">Whether to allow retries if needed.</param> /// <param name="activationTimestamp">The datetime to activate the task (otherwise ASAP).</param> public static string AddTask <TSettings> ( this TaskProcessorBase <TSettings> taskProcessor, string taskQueue, string taskType, TaskQueueDirective directive = null, bool allowRetry = true, DateTime?activationTimestamp = null ) where TSettings : AppTaskProcessorSettings { // Use the other overload return(taskProcessor.AddTask <TSettings, TaskQueueDirective> ( taskQueue, taskType, directive, allowRetry: allowRetry, activationTimestamp )); }
/// <summary> /// Processes a single job. /// </summary> /// <param name="job">Task processor job.</param> private void ProcessSequentialTask(TaskProcessorJob job) { // Debug Logging. if (this.Configuration.LoggingEnabled) { Debug.WriteLine($"Sequential task processing with task id => {job.Data?.Value.Id}."); } // Ensure cancellation has not been requested. job.ThrowIfCancellationRequested(); // Update the progress of the task in the task queue. this.TaskProcessor.UpdateTaskAsAssignedToProcessor(job); // Sanity. if (null == job.Data?.Value) { return; } // Deserialize the directive. var dir = TaskQueueDirective.Parse <ObjVerExTaskQueueDirective>(job.Data?.Value); // Sanity. if (string.IsNullOrWhiteSpace(dir?.ObjVerEx)) { return; } // Update the object. try { // Mark that we're updating the object. this.TaskProcessor.UpdateTaskInfo ( job.Data?.Value, MFTaskState.MFTaskStateInProgress, $"Updating object {dir.ObjVerEx}", false ); // Load the object, check it out, update, check it in. var objVerEx = ObjVerEx.Parse(job.Vault, dir.ObjVerEx); objVerEx.CheckOut(); objVerEx.SetProperty ( MFBuiltInPropertyDef.MFBuiltInPropertyDefNameOrTitle, MFDataType.MFDatatypeText, DateTime.Now.ToLongTimeString() ); objVerEx.SaveProperties(); objVerEx.CheckIn(); // Updated. this.TaskProcessor.UpdateTaskInfo ( job.Data?.Value, MFTaskState.MFTaskStateCompleted, $"Object {dir.ObjVerEx} updated", false ); } catch (Exception e) { // Exception. this.TaskProcessor.UpdateTaskInfo ( job.Data?.Value, MFTaskState.MFTaskStateFailed, e.Message, false ); } }
/// <summary> /// Marks any future executions of this job in this queue as cancelled. /// </summary> /// <param name="backgroundOperationName">If set, cancels only future executions for the specified background operation.</param> /// <param name="remarks">Remarks to set on the cancellation.</param> public void CancelFutureExecutions(string backgroundOperationName = null, string remarks = null) { try { // Cancel any tasks that are already scheduled. var tasksToCancel = TaskQueueAdministrator.FindTasks ( this.VaultApplication.PermanentVault, this.QueueId, t => t.Type == TaskQueueBackgroundOperation <TSecureConfiguration> .TaskTypeId, new[] { MFTaskState.MFTaskStateWaiting } ); foreach (var task in tasksToCancel.Cast <ApplicationTaskInfo>()) { var applicationTask = task.ToApplicationTask(); // Skip any that are not for this background operation. if (false == string.IsNullOrWhiteSpace(backgroundOperationName)) { var backgroundOperationDirective = TaskQueueDirective.Parse <BackgroundOperationTaskDirective>(applicationTask); if (null == backgroundOperationDirective?.BackgroundOperationName) { continue; } if (!backgroundOperationDirective.BackgroundOperationName.Equals(backgroundOperationName)) { continue; } } try { // Mark each task as superseded. switch (task.State) { case MFTaskState.MFTaskStateInProgress: this.VaultApplication.TaskManager.CancelActiveTask ( this.VaultApplication.PermanentVault, task.TaskID ); break; case MFTaskState.MFTaskStateWaiting: this.VaultApplication.TaskManager.CancelWaitingTask ( this.VaultApplication.PermanentVault, task.TaskID ); break; default: // Cannot cancel ones in other states. break; } } catch (Exception e) { SysUtils.ReportErrorToEventLog ( $"Exception cancelling task {task.TaskID} of type {TaskQueueBackgroundOperation<TSecureConfiguration>.TaskTypeId} on queue {this.QueueId} to cancel.", e ); } } } catch (Exception e) { SysUtils.ReportErrorToEventLog ( $"Exception retrieving tasks of type {TaskQueueBackgroundOperation<TSecureConfiguration>.TaskTypeId} on queue {this.QueueId} to cancel.", e ); } }
/// <inheritdoc /> public override void RunJob(TaskProcessorJob job, TaskQueueDirective directive) { // Execute the callback. this.UserMethod(job, directive as TDirective); }