/// <summary>
        /// Submits a task with the specified parameters.
        /// </summary>
        /// <param name="taskId">The unique ID of the task.</param>
        /// <param name="task">The task to submit.</param>
        /// <param name="summary">The summary to associated with the task, if any.</param>
        /// <param name="priority">The priority of the task.</param>
        internal void SubmitTask(Guid taskId, ITask task, ITaskSummary summary, TaskPriority priority)
        {
            if (task == null)
            {
                throw new ArgumentNullException("task");
            }

            Trace.WriteLine("ENTER: Submitting '{0}' with priority '{1}' ...".FormatInvariant(task.GetType().Name, priority));

            string pollingQueueKey = this.configuration.GetPollingQueueKey(task.GetType());

            this.repository.Tasks.Add(taskId, task);

            if (summary != null)
            {
                this.repository.TaskSummary.Add(taskId, summary);
            }

            ITaskRuntimeInfo taskInfo = this.repository.TaskRuntimeInfo.Create(taskId, task.GetType(), this.dateTimeProvider.UtcNow, priority, pollingQueueKey);

            this.repository.TaskRuntimeInfo.Add(taskInfo);

            ITaskMessageBusSender taskMessageBus = this.messageBus.Tasks.GetSender(task.GetType());

            taskMessageBus.NotifyTaskSubmitted(taskId, this.dateTimeProvider.UtcNow, !string.IsNullOrEmpty(pollingQueueKey));

            Trace.WriteLine("EXIT: Task '{0}' submitted with ID '{1}' ...".FormatInvariant(task, taskId));
        }
        /// <inheritdoc />
        public void CancelTask(Guid taskId)
        {
            Trace.WriteLine("ENTER: Cancelling task '{0}' ...".FormatInvariant(taskId));

            Lazy <DateTime> timestampUtc = new Lazy <DateTime>(() => this.dateTimeProvider.UtcNow);

            ITaskRuntimeInfo taskInfo = this.repository.TaskRuntimeInfo.GetById(taskId);

            if (taskInfo == null)
            {
                throw new KeyNotFoundException("Task '{0}' was not found.".FormatInvariant(taskId));
            }

            switch (taskInfo.Status)
            {
            case TaskStatus.Canceled:
            case TaskStatus.Failed:
            case TaskStatus.Success:
                throw new InvalidOperationException("Task '{0}' status is {1} and will not be canceled.".FormatInvariant(taskId, taskInfo.Status));
            }

            ITaskMessageBusSender taskMessageBus = this.messageBus.Tasks.GetSender(taskInfo.TaskType);

            taskMessageBus.NotifyTaskCancelRequest(taskId, timestampUtc.Value);

            this.repository.TaskRuntimeInfo.RequestCancel(taskId, timestampUtc.Value);

            Trace.WriteLine("EXIT: Task '{0}' canceled.".FormatInvariant(taskId));
        }
Beispiel #3
0
        private bool AssignTaskToProcessor(Guid taskId, Type taskType, Guid taskProcessorId)
        {
            Trace.WriteLine("ENTER: Assigning task '{0}' to processor '{1}' ...".FormatInvariant(taskId, taskProcessorId));

            this.repository.TaskRuntimeInfo.Assign(taskId, taskProcessorId);

            using (ManualResetEventSlim blocker = new ManualResetEventSlim())
            {
                this.assignTaskWaitHandlers.TryAdd(taskId, blocker);

                ITaskMessageBusSender taskMessageBus = this.messageBus.Tasks.GetSender(taskType);

                ThreadPool.QueueUserWorkItem(state =>
                {
                    taskMessageBus.NotifyTaskAssigned(taskId, taskProcessorId);
                });

                bool result = blocker.Wait(this.assignTaskTimeout);

                ManualResetEventSlim blocker1;

                this.assignTaskWaitHandlers.TryRemove(taskId, out blocker1);

                if (result)
                {
                    Trace.WriteLine("EXIT: Task '{0}' assigned successfully to processor '{1}'.".FormatInvariant(taskId, taskProcessorId));
                }
                else
                {
                    Trace.WriteLine("EXIT: Failed to assign task '{0}' to processor '{1}'. Response was not receive after {2} timeout.".FormatInvariant(taskId, taskProcessorId, this.assignTaskTimeout));
                }

                return(result);
            }
        }
        public void GetTaskSender()
        {
            CompositeTaskMessageBus composite = new CompositeTaskMessageBus();

            composite.Senders.Add(new FakeTaskMessageBus());
            composite.Senders.Add(new FakeTaskMessageBus());

            composite.Senders.OfType <FakeTaskMessageBus>().First().PredefineResult(false, mb => mb.IsSupported(typeof(FakeTask)));
            composite.Senders.OfType <FakeTaskMessageBus>().Last().PredefineResult(true, mb => mb.IsSupported(typeof(FakeTask)));

            ITaskMessageBusSender result = composite.GetSender <FakeTask>();

            result.NotifyTaskProgress(Guid.Empty, 0);

            composite.Senders.OfType <FakeTaskMessageBus>().First().AssertNoMethodCall(mb => mb.NotifyTaskProgress(Guid.Empty, 0));
            composite.Senders.OfType <FakeTaskMessageBus>().Last().AssertMethodCallOnce(mb => mb.NotifyTaskProgress(Guid.Empty, 0));
        }
Beispiel #5
0
        public void StartTask(Guid taskId)
        {
            ITask task = this.repository.Tasks.GetById(taskId);

            if (task == null)
            {
                throw new ArgumentException("Task '{0}' was not found in storage.".FormatInvariant(taskId), "taskId");
            }

            ITaskWorker taskWorker = this.taskFactory.CreateTaskWorker(task);

            ITaskMessageBusSender taskMessageBus = this.messageBus.Tasks.GetSender(task.GetType());

            taskWorker.ReportProgress += (sender, e) =>
            {
                this.repository.TaskRuntimeInfo.Progress(taskId, e.Percentage);

                taskMessageBus.NotifyTaskProgress(taskId, e.Percentage);
            };

            this.messageBus.Tasks.Receiver.SubscribeForChannels(MessageBusChannel.TaskCancelRequest);

            bool isCanceled = false;

            this.messageBus.Tasks.Receiver.TaskCancelRequested += (_, e1) =>
            {
                if (!isCanceled && (e1.TaskId == taskId))
                {
                    isCanceled = true;

                    taskWorker.CancelTask();
                }
            };

            ITaskJobSettings settings = null;

            ITaskWorkerConfiguration config = this.configuration[task.GetType()];

            if ((config != null) && config.HasTaskJobSettings)
            {
                settings = this.repository.TaskJobSettings.Get(task.GetType());
            }

            ITaskRuntimeInfo taskInfo = this.repository.TaskRuntimeInfo.GetById(taskId);

            if (taskInfo == null)
            {
                throw new ArgumentException("Task '{0}' not found in storage.".FormatInvariant(taskId), "taskId");
            }

            switch (taskInfo.Status)
            {
            case TaskStatus.Pending:
            case TaskStatus.InProgress:
                break;

            case TaskStatus.Canceled:
                throw new OperationCanceledException();

            default:
                throw new ArgumentException("Task '{0}' status is '{1}'.".FormatInvariant(taskId, taskInfo.Status), "taskId");
            }

            try
            {
                try
                {
                    taskWorker.StartTask(task, settings);
                }
                catch (Exception ex)
                {
                    this.repository.TaskRuntimeInfo.Fail(taskId, this.dateTimeProvider.UtcNow, ex);

                    throw;
                }
            }
            finally
            {
                this.messageBus.Tasks.Receiver.UnsubscribeFromAllChannels();

                if (taskWorker is IDisposable)
                {
                    ((IDisposable)taskWorker).Dispose();
                }
            }
        }