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
                );
            }
        }
예제 #3
0
 /// <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;
 }
예제 #4
0
        public void RunAtIntervals(string name, TimeSpan interval, TaskQueueDirective directive = null)
        {
            if (!BackgroundOperations.Keys.Contains(name))
            {
                return;
            }

            BackgroundOperations[name].Operation.RunAtIntervals(interval, directive);
        }
예제 #5
0
        public void RunOnce(string name, DateTime?runAt = null, TaskQueueDirective directive = null)
        {
            if (!BackgroundOperations.Keys.Contains(name))
            {
                return;
            }

            BackgroundOperations[name].Operation.RunOnce(runAt, directive);
        }
예제 #6
0
        /// <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));
        }
예제 #7
0
 /// <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
            ));
 }
예제 #9
0
 /// <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
            ));
 }
예제 #10
0
 /// <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
                );
            }
        }
예제 #12
0
        /// <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
                );
            }
        }
예제 #13
0
 /// <inheritdoc />
 public override void RunJob(TaskProcessorJob job, TaskQueueDirective directive)
 {
     // Execute the callback.
     this.UserMethod(job, directive as TDirective);
 }