/// <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));
        }
        public void StartPollingQueueTask()
        {
            ITaskRuntimeInfo taskInfo1 = this.Repository.Add("Test");

            Guid taskProcessorId = Guid.NewGuid();

            DateTime timestampUtc = DateTime.UtcNow;

            this.Repository.Start(taskInfo1.TaskId, taskProcessorId, timestampUtc);

            ITaskRuntimeInfo taskInfo2 = this.Repository.GetById(taskInfo1.TaskId);

            Assert.AreEqual(TaskStatus.InProgress, taskInfo2.Status);
            Assert.AreEqual(taskProcessorId, taskInfo2.TaskProcessorId);
            Assert.AreEqual(timestampUtc, taskInfo2.StartedUtc);

            Assert.IsTrue(this.Repository.CheckIsPendingOrActive(taskInfo1.TaskId));
            Assert.IsFalse(this.Repository.GetPending(false).Any(t => t.TaskId == taskInfo1.TaskId));
            Assert.IsFalse(this.Repository.GetPending(true).Any(t => t.TaskId == taskInfo1.TaskId));
            Assert.IsFalse(this.Repository.GetPendingAndActive()[TaskStatus.Pending].Any(t => t.TaskId == taskInfo1.TaskId));
            Assert.IsTrue(this.Repository.GetPendingAndActive()[TaskStatus.InProgress].Any(t => t.TaskId == taskInfo1.TaskId));
            Assert.IsTrue(this.Repository.GetActive().Any(t => t.TaskId == taskInfo1.TaskId));
            Assert.IsFalse(this.Repository.GetFailed().Any(t => t.TaskId == taskInfo1.TaskId));
            Assert.IsFalse(this.Repository.GetArchive().Any(t => t.TaskId == taskInfo1.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));
        }
        private static bool CanExecuteTask(ITaskRuntimeInfo pendingTaskInfo, ITaskProcessorRuntimeInfo processorInfo, IEnumerable <ITaskRuntimeInfo> activeTaskInfo)
        {
            Trace.WriteLine("ENTER: Checking if task processor '{0}' can execute task '{1}' ...".FormatInvariant(processorInfo.TaskProcessorId, pendingTaskInfo.TaskId));

            if (processorInfo.Configuration.Tasks.MaxWorkers.HasValue &&
                activeTaskInfo.AtLeast(processorInfo.Configuration.Tasks.MaxWorkers.Value, t => t.TaskProcessorId == processorInfo.TaskProcessorId))
            {
                Trace.WriteLine("EXIT: Task processor '{0}' cannot execute task '{1}' because max workers threshold {2} is reached.".FormatInvariant(processorInfo.TaskProcessorId, pendingTaskInfo.TaskId, processorInfo.Configuration.Tasks.MaxWorkers.Value));

                return(false);
            }

            ITaskJobConfiguration taskJobConfig = processorInfo.Configuration.Tasks[pendingTaskInfo.TaskType];

            if ((taskJobConfig != null) && taskJobConfig.MaxWorkers.HasValue &&
                activeTaskInfo.AtLeast(taskJobConfig.MaxWorkers.Value, tt => (tt.TaskType == taskJobConfig.TaskType) && (tt.TaskProcessorId == processorInfo.TaskProcessorId)))
            {
                Trace.WriteLine("Task processor '{0}' cannot execute task '{1}' because max workers threshold {2} for task type '{3}' is reached.".FormatInvariant(processorInfo.TaskProcessorId, pendingTaskInfo.TaskId, taskJobConfig.MaxWorkers.Value, pendingTaskInfo.TaskType.Name));

                return(false);
            }

            Trace.WriteLine("EXIT: Task processor '{0}' can execute task '{1}'.".FormatInvariant(processorInfo.TaskProcessorId, pendingTaskInfo.TaskId));

            return(true);
        }
        public void ChooseProcessorForTask()
        {
            ITaskProcessorRuntimeInfo processorInfo1 = new FakeTaskProcessorRuntimeInfo()
            {
                TaskProcessorId = Guid.NewGuid()
            };

            this.Repository.TaskProcessorRuntimeInfo.Add(processorInfo1);

            ITaskProcessorRuntimeInfo processorInfo2 = new FakeTaskProcessorRuntimeInfo()
            {
                TaskProcessorId = Guid.NewGuid()
            };

            this.Repository.TaskProcessorRuntimeInfo.Add(processorInfo2);

            ITaskRuntimeInfo activeTaskInfo = this.Repository.TaskRuntimeInfo.Create();

            this.Repository.TaskRuntimeInfo.Add(activeTaskInfo);

            this.Repository.TaskRuntimeInfo.Start(activeTaskInfo.TaskId, processorInfo1.TaskProcessorId, DateTime.UtcNow);

            var result = this.TaskDistributor.ChooseProcessorForTask(new FakeTaskRuntimeInfo());

            Assert.AreEqual(processorInfo2, result.First());
            Assert.AreEqual(processorInfo1, result.Last());
        }
        public void StartTaskWithTaskJobSettings()
        {
            this.Configuration.Get <FakeTask>().HasTaskJobSettings = true;

            ITaskJobSettings settings = new FakeTaskJobSettings();

            this.Repository.TaskJobSettings.Set <FakeTask>(settings);

            ITaskRuntimeInfo taskInfo = this.Repository.TaskRuntimeInfo.Create();

            FakeTask task = new FakeTask();

            this.Repository.Tasks.Add(taskInfo.TaskId, task);

            this.Repository.TaskRuntimeInfo.Add(taskInfo);

            using (FakeTaskWorker taskWorker = new FakeTaskWorker())
            {
                this.TaskWorkerFactory.PredefineResult(taskWorker, f => f.CreateTaskWorker(task));

                this.DateTimeProvider.UtcNow = DateTime.UtcNow;

                this.TaskWorkerBootstrap.StartTask(taskInfo.TaskId);

                this.TaskWorkerFactory.AssertMethodCallOnceWithArguments(f => f.CreateTaskWorker(task));

                taskWorker.AssertMethodCallOnce(w => w.StartTask(task, settings));
            }
        }
        public void CancelTask()
        {
            ITaskRuntimeInfo taskInfo = this.Repository.TaskRuntimeInfo.Create();

            this.Repository.TaskRuntimeInfo.Add(taskInfo);

            ITask task = new FakeTask();

            this.Repository.Tasks.Add(taskInfo.TaskId, task);

            using (FakeTaskWorker taskWorker = new FakeTaskWorker())
            {
                this.TaskWorkerFactory.PredefineResult(taskWorker, f => f.CreateTaskWorker(task));

                taskWorker.PredefineMethodCall(w => w.StartTask(task, null), () => Thread.Sleep(TimeSpan.FromSeconds(1)));

                ThreadPool.QueueUserWorkItem(_ => this.TaskWorkerBootstrap.StartTask(taskInfo.TaskId));

                Thread.Sleep(TimeSpan.FromSeconds(0.5));

                this.DateTimeProvider.UtcNow = DateTime.UtcNow;

                this.MessageBus.Tasks.NotifyTaskCancelRequest(taskInfo.TaskId, this.DateTimeProvider.UtcNow);

                Thread.Sleep(TimeSpan.FromSeconds(1.5));

                taskWorker.AssertMethodCallOnce(w => w.CancelTask());
                taskWorker.AssertMethodCallOnce(w => w.Dispose());
            }

            this.MessageBus.Tasks.Receiver.AssertMethodCallOnce(mb => mb.UnsubscribeFromAllChannels());
        }
        public void Fail()
        {
            ITaskRuntimeInfo taskInfo = this.Repository.TaskRuntimeInfo.Add();

            ITask task = new FakeTask();

            this.Repository.Tasks.Add(taskInfo.TaskId, task);

            this.DateTimeProvider.UtcNow = DateTime.UtcNow;

            Exception error = new TypeNotFoundInRedisException("Dummy Error");

            using (FakeTaskWorker worker = new FakeTaskWorker())
            {
                worker.PredefineMethodCall(w => w.StartTask(task, null), () => { throw error; });

                this.TaskWorkerFactory.PredefineResult(worker, f => f.CreateTaskWorker(task));

                try
                {
                    this.TaskWorkerBootstrap.StartTask(taskInfo.TaskId);
                }
                catch (TypeNotFoundInRedisException)
                {
                }

                worker.AssertMethodCallOnce(w => w.Dispose());
            }

            this.MessageBus.Tasks.Receiver.AssertMethodCallOnce(mb => mb.UnsubscribeFromAllChannels());

            this.Repository.TaskRuntimeInfo.AssertMethodCallOnceWithArguments(r => r.Fail(taskInfo.TaskId, this.DateTimeProvider.UtcNow, error));
        }
        public void CancelTaskMultipleTimes()
        {
            ITaskRuntimeInfo taskInfo = this.Repository.TaskRuntimeInfo.Add();

            ITask task = new FakeTask();

            this.Repository.Tasks.Add(taskInfo.TaskId, task);

            using (FakeTaskWorker taskWorker = new FakeTaskWorker())
            {
                taskWorker.PredefineMethodCall(w => w.StartTask(task, null), () => Thread.Sleep(TimeSpan.FromSeconds(1)));

                this.TaskWorkerFactory.PredefineResult(taskWorker, f => f.CreateTaskWorker(task));

                for (int i = 0; i < 3; i++)
                {
                    ThreadPool.QueueUserWorkItem(_ =>
                    {
                        Thread.Sleep(TimeSpan.FromSeconds(0.3));

                        this.MessageBus.Tasks.NotifyTaskCancelRequest(taskInfo.TaskId, DateTime.UtcNow);
                    });
                }

                this.TaskWorkerBootstrap.StartTask(taskInfo.TaskId);

                Thread.Sleep(TimeSpan.FromSeconds(0.5));

                taskWorker.AssertMethodCallOnceWithArguments(w => w.CancelTask());
            }

            this.MessageBus.Tasks.Receiver.AssertMethodCallOnce(mb => mb.UnsubscribeFromAllChannels());
        }
        private void RequestCancel(bool startTask)
        {
            ITaskRuntimeInfo taskInfo = this.Repository.Add();

            if (startTask)
            {
                this.Repository.Start(taskInfo.TaskId, Guid.NewGuid(), DateTime.UtcNow.AddMinutes(-1));
            }

            DateTime timestampUtc = DateTime.UtcNow;

            this.Repository.RequestCancel(taskInfo.TaskId, timestampUtc);

            ITaskRuntimeInfo taskInfo2 = this.Repository.GetById(taskInfo.TaskId);

            Assert.AreEqual(TaskStatus.Canceled, taskInfo2.Status);

            this.AssertEqual(timestampUtc, taskInfo2.CanceledUtc.Value);

            Assert.IsFalse(this.Repository.CheckIsPendingOrActive(taskInfo.TaskId));
            Assert.IsFalse(this.Repository.GetPending(false).Any(t => t.TaskId == taskInfo.TaskId));
            Assert.IsFalse(this.Repository.GetPending(true).Any(t => t.TaskId == taskInfo.TaskId));
            Assert.IsFalse(this.Repository.GetPendingAndActive()[TaskStatus.Pending].Any(t => t.TaskId == taskInfo.TaskId));
            Assert.IsFalse(this.Repository.GetPendingAndActive()[TaskStatus.InProgress].Any(t => t.TaskId == taskInfo.TaskId));
            Assert.IsFalse(this.Repository.GetActive().Any(t => t.TaskId == taskInfo.TaskId));
            Assert.IsFalse(this.Repository.GetFailed().Any(t => t.TaskId == taskInfo.TaskId));
            Assert.IsTrue(this.Repository.GetArchive().Any(t => t.TaskId == taskInfo.TaskId));
        }
        public void Complete()
        {
            ITaskRuntimeInfo taskInfo1 = this.Repository.Add();

            Guid taskProcessorId = Guid.NewGuid();

            DateTime timestampUtc = DateTime.UtcNow;

            this.Repository.Start(taskInfo1.TaskId, taskProcessorId, DateTime.UtcNow.AddMinutes(-1));
            this.Repository.Complete(taskInfo1.TaskId, timestampUtc);

            ITaskRuntimeInfo taskInfo2 = this.Repository.GetById(taskInfo1.TaskId);

            Assert.AreEqual(100, taskInfo2.Percentage);

            Assert.AreEqual(TaskStatus.Success, taskInfo2.Status);

            this.AssertEqual(timestampUtc, taskInfo2.CompletedUtc.Value);

            Assert.IsFalse(this.Repository.CheckIsPendingOrActive(taskInfo1.TaskId));
            Assert.IsFalse(this.Repository.GetPending(false).Any(t => t.TaskId == taskInfo1.TaskId));
            Assert.IsFalse(this.Repository.GetPending(true).Any(t => t.TaskId == taskInfo1.TaskId));
            Assert.IsFalse(this.Repository.GetPendingAndActive()[TaskStatus.Pending].Any(t => t.TaskId == taskInfo1.TaskId));
            Assert.IsFalse(this.Repository.GetPendingAndActive()[TaskStatus.InProgress].Any(t => t.TaskId == taskInfo1.TaskId));
            Assert.IsFalse(this.Repository.GetActive().Any(t => t.TaskId == taskInfo1.TaskId));
            Assert.IsFalse(this.Repository.GetFailed().Any(t => t.TaskId == taskInfo1.TaskId));
            Assert.IsTrue(this.Repository.GetArchive().Any(t => t.TaskId == taskInfo1.TaskId));
        }
        public void Fail()
        {
            ITaskRuntimeInfo taskInfo = this.Repository.Add();

            Guid taskProcessorId = Guid.NewGuid();

            DateTime timestampUtc = DateTime.UtcNow;

            Exception error = new TypeNotFoundInRedisException("Hello Error");

            this.Repository.Start(taskInfo.TaskId, taskProcessorId, DateTime.UtcNow.AddMinutes(-1));
            this.Repository.Fail(taskInfo.TaskId, timestampUtc, error);

            taskInfo = this.Repository.GetById(taskInfo.TaskId);

            Assert.AreEqual(TaskStatus.Failed, taskInfo.Status);

            this.AssertEqual(timestampUtc, taskInfo.CompletedUtc.Value);

            Assert.AreEqual(error.ToString(), taskInfo.Error);

            Assert.IsFalse(this.Repository.CheckIsPendingOrActive(taskInfo.TaskId));
            Assert.IsFalse(this.Repository.GetPending(false).Any(t => t.TaskId == taskInfo.TaskId));
            Assert.IsFalse(this.Repository.GetPending(true).Any(t => t.TaskId == taskInfo.TaskId));
            Assert.IsFalse(this.Repository.GetPendingAndActive()[TaskStatus.Pending].Any(t => t.TaskId == taskInfo.TaskId));
            Assert.IsFalse(this.Repository.GetPendingAndActive()[TaskStatus.InProgress].Any(t => t.TaskId == taskInfo.TaskId));
            Assert.IsFalse(this.Repository.GetActive().Any(t => t.TaskId == taskInfo.TaskId));
            Assert.IsTrue(this.Repository.GetFailed().Any(t => t.TaskId == taskInfo.TaskId));
            Assert.IsTrue(this.Repository.GetArchive().Any(t => t.TaskId == taskInfo.TaskId));
        }
        public void ReportProgress()
        {
            ITaskRuntimeInfo taskInfo = this.Repository.TaskRuntimeInfo.Create();

            this.Repository.TaskRuntimeInfo.Add(taskInfo);

            FakeTask task = new FakeTask();

            this.Repository.Tasks.Add(taskInfo.TaskId, task);

            double percent = DateTime.Now.Second;

            using (FakeTaskWorker worker = new FakeTaskWorker())
            {
                this.TaskWorkerFactory.PredefineResult(worker, f => f.CreateTaskWorker(task));

                this.TaskWorkerBootstrap.StartTask(taskInfo.TaskId);

                worker.RaiseReportProgress(percent);
            }

            this.MessageBus.Tasks.Receiver.AssertMethodCallOnceWithArguments(mb => mb.NotifyTaskProgress(taskInfo.TaskId, percent));

            this.Repository.TaskRuntimeInfo.AssertMethodCallOnceWithArguments(r => r.Progress(taskInfo.TaskId, percent));
        }
        internal static ITaskRuntimeInfo Add(this ITaskRuntimeInfoRepository repository, string pollingQueue)
        {
            ITaskRuntimeInfo result = repository.Create(Guid.NewGuid(), typeof(FakeTask), DateTime.UtcNow, TaskPriority.Normal, pollingQueue);

            repository.Add(result);

            return(result);
        }
        internal static ITaskRuntimeInfo Add(this ITaskRuntimeInfoRepository repository)
        {
            ITaskRuntimeInfo result = repository.Create();

            repository.Add(result);

            return(result);
        }
        public void ChooseNextTaskForProcessorNoProcessor()
        {
            ITaskRuntimeInfo pendingTaskInfo = this.Repository.TaskRuntimeInfo.Create();

            this.Repository.TaskRuntimeInfo.Add(pendingTaskInfo);

            Assert.IsFalse(this.TaskDistributor.ChooseNextTasksForProcessor(Guid.NewGuid()).Any());
        }
Example #17
0
        private void OnShowTaskErrorClick(object sender, RoutedEventArgs e)
        {
            TaskViewModel taskViewModel = (TaskViewModel)((FrameworkElement)sender).DataContext;

            ITaskRuntimeInfo taskInfo = this.ViewModel.TaskProcessorFacade.GetTaskRuntimeInfo(taskViewModel.TaskId);

            MessageBox.Show(taskInfo.Error, "Task Error", MessageBoxButton.OK, MessageBoxImage.Error);
        }
        internal static ITaskRuntimeInfo Add(this ITaskRuntimeInfoRepository repository, TaskPriority priority)
        {
            ITaskRuntimeInfo result = repository.Create(Guid.NewGuid(), typeof(FakeTask), DateTime.UtcNow, priority, null);

            repository.Add(result);

            return(result);
        }
        private void ChooseNextTaskForProcessorOrder(TaskPriority higher, TaskPriority smaller)
        {
            ITaskRuntimeInfo taskInfo1 = this.Repository.TaskRuntimeInfo.Add(smaller);
            ITaskRuntimeInfo taskInfo2 = this.Repository.TaskRuntimeInfo.Add(higher);

            IEnumerable <ITaskRuntimeInfo> result = this.TaskDistributor.ChooseNextTasksForProcessor(Guid.NewGuid());

            Assert.AreEqual(2, result.Count());
            Assert.AreEqual(taskInfo2, result.First());
            Assert.AreEqual(taskInfo1, result.Last());
        }
Example #20
0
        private void OnTaskSubmitted(object sender, TaskEventArgs e)
        {
            ITaskRuntimeInfo taskInfo = this.taskProcessorFacade.GetTaskRuntimeInfo(e.TaskId);

            if (taskInfo != null)
            {
                App.Current.Dispatcher.InvokeAsync(() =>
                {
                    this.pendingTasks.Add(new TaskViewModel(taskInfo));
                });
            }
        }
        /// <inheritdoc />
        public IEnumerable <ITaskProcessorRuntimeInfo> ChooseProcessorForTask(ITaskRuntimeInfo pendingTaskInfo)
        {
            if (pendingTaskInfo == null)
            {
                throw new ArgumentNullException("pendingTaskInfo");
            }

            ITaskRuntimeInfo[] activeTasksInfo = this.repository.TaskRuntimeInfo.GetActive().ToArray();

            return(this.repository.TaskProcessorRuntimeInfo.GetAll()
                   .Where(processorInfo => DefaultTaskDistributor.CanExecuteTask(pendingTaskInfo, processorInfo, activeTasksInfo))
                   .OrderBy(t => activeTasksInfo.Count(tt => tt.TaskProcessorId == t.TaskProcessorId)));
        }
        public void Add(ITaskRuntimeInfo taskInfo)
        {
            if (taskInfo == null)
            {
                throw new ArgumentNullException(nameof(taskInfo));
            }

            taskInfo.ValidateForAdd();

            this.RecordMethodCall(taskInfo);

            this.taskInfos.Add(taskInfo.TaskId, (FakeTaskRuntimeInfo)taskInfo);
        }
 internal TaskViewModel(ITaskRuntimeInfo taskInfo)
 {
     this.taskId          = taskInfo.TaskId;
     this.taskType        = taskInfo.TaskType;
     this.priority        = taskInfo.Priority;
     this.submittedUtc    = taskInfo.SubmittedUtc;
     this.status          = taskInfo.Status.ToString();
     this.startedUtc      = taskInfo.StartedUtc;
     this.canceledUtc     = taskInfo.CanceledUtc;
     this.completedUtc    = taskInfo.CompletedUtc;
     this.taskProcessorId = taskInfo.TaskProcessorId;
     this.pollingQueue    = taskInfo.PollingQueue;
     this.error           = taskInfo.Error;
 }
        public void Create()
        {
            Guid taskId = Guid.NewGuid();

            DateTime timestampUtc = DateTime.UtcNow.AddMinutes(-1);

            ITaskRuntimeInfo taskInfo = this.Repository.Create(taskId, typeof(FakeTask), timestampUtc, TaskPriority.VeryHigh, "Polling Queue");

            Assert.AreEqual(taskId, taskInfo.TaskId);
            Assert.AreEqual(typeof(FakeTask), taskInfo.TaskType);
            Assert.AreEqual(TaskPriority.VeryHigh, taskInfo.Priority);
            Assert.AreEqual(TaskStatus.Pending, taskInfo.Status);
            Assert.AreEqual(timestampUtc, taskInfo.SubmittedUtc);
            Assert.AreEqual("Polling Queue", taskInfo.PollingQueue);
            Assert.IsNull(taskInfo.Error);
        }
        public void UpdateProgress()
        {
            ITaskRuntimeInfo taskInfo = this.Repository.Add();

            this.Repository.Progress(taskInfo.TaskId, 100);

            taskInfo = this.Repository.GetById(taskInfo.TaskId);

            Assert.AreEqual(100, taskInfo.Percentage);

            this.Repository.Progress(taskInfo.TaskId, 0);

            taskInfo = this.Repository.GetById(taskInfo.TaskId);

            Assert.AreEqual(0, taskInfo.Percentage);
        }
        private Dictionary <TaskStatus, IEnumerable <ITaskRuntimeInfo> > GetAllByType(params string[] listKeys)
        {
            List <string> entityIds = new List <string>();

            using (IRedisPipeline pipeline = this.provider.CreatePipeline())
            {
                foreach (string listKey in listKeys)
                {
                    pipeline.GetList(listKey, values => entityIds.AddRange(values));
                }

                pipeline.Flush();
            }

            Dictionary <TaskStatus, IEnumerable <ITaskRuntimeInfo> > result = new Dictionary <TaskStatus, IEnumerable <ITaskRuntimeInfo> >();

            using (IRedisPipeline pipeline = this.provider.CreatePipeline())
            {
                foreach (string entityId in entityIds)
                {
                    string entityKey = RedisTaskRuntimeInfoRepository.GetEntityKey(entityId);

                    pipeline.GetHash(entityKey, values =>
                    {
                        if (values.Count > 0)
                        {
                            ITaskRuntimeInfo taskInfo = RedisTaskRuntimeInfoRepository.Convert(values);

                            IEnumerable <ITaskRuntimeInfo> collection;

                            if (!result.TryGetValue(taskInfo.Status, out collection))
                            {
                                collection = new List <ITaskRuntimeInfo>();

                                result.Add(taskInfo.Status, collection);
                            }

                            ((ICollection <ITaskRuntimeInfo>)collection).Add(taskInfo);
                        }
                    });
                }

                pipeline.Flush();
            }

            return(result);
        }
        /// <inheritdoc />
        public void Add(ITaskRuntimeInfo taskInfo)
        {
            if (taskInfo == null)
            {
                throw new ArgumentNullException("taskInfo");
            }

            Trace.WriteLine("ENTER: Adding runtime information for task '{0}' of type '{1}' with priority '{2}' in polling queue '{3}' ...".FormatInvariant(taskInfo.TaskId, taskInfo.TaskType, taskInfo.Priority, taskInfo.PollingQueue));

            taskInfo.ValidateForAdd();

            string entityKey = RedisTaskRuntimeInfoRepository.GetEntityKey(taskInfo.TaskId);

            string addToListKey;

            Dictionary <string, string> values = new Dictionary <string, string>()
            {
                { "Id", RedisConverter.ToString(taskInfo.TaskId) },
                { "TaskType", RedisConverter.ToString(taskInfo.TaskType, true) },
                { "SubmittedUtc", RedisConverter.ToString(taskInfo.SubmittedUtc) },
                { "Status", RedisConverter.ToString(taskInfo.Status) }
            };

            if (string.IsNullOrEmpty(taskInfo.PollingQueue))
            {
                values.Add("Priority", RedisConverter.ToString(taskInfo.Priority));

                addToListKey = RedisTaskRuntimeInfoRepository.PendingTasksList;
            }
            else
            {
                values.Add("PollingQueue", taskInfo.PollingQueue);

                addToListKey = RedisTaskRuntimeInfoRepository.GetPollingQueueRedisKey(taskInfo.PollingQueue, TaskStatus.Pending);
            }

            using (IRedisTransaction transaction = this.Provider.CreateTransaction())
            {
                transaction.SetHashValues(entityKey, values);

                transaction.AddToList(addToListKey, RedisConverter.ToString(taskInfo.TaskId));

                transaction.Commit();
            }

            Trace.WriteLine("EXIT: Runtime information for task '{0}' of type '{1}' with priority '{2}' in polling queue '{3}' added.".FormatInvariant(taskInfo.TaskId, taskInfo.TaskType, taskInfo.Priority, taskInfo.PollingQueue));
        }
        public void AddPollingQueueTask()
        {
            ITaskRuntimeInfo taskInfo1 = this.Repository.Add("Test");
            ITaskRuntimeInfo taskInfo2 = this.Repository.GetById(taskInfo1.TaskId);

            UnitTestHelpers.AssertEqualByPublicScalarProperties(taskInfo1, taskInfo2);

            Assert.IsTrue(this.Repository.CheckIsPendingOrActive(taskInfo1.TaskId));
            Assert.IsFalse(this.Repository.GetPending(false).Any(t => t.TaskId == taskInfo1.TaskId));
            Assert.IsTrue(this.Repository.GetPending(true).Any(t => t.TaskId == taskInfo1.TaskId));
            Assert.IsFalse(this.Repository.GetPendingAndActive()[TaskStatus.Pending].Any(t => t.TaskId == taskInfo1.TaskId));
            Assert.IsFalse(this.Repository.GetPendingAndActive()[TaskStatus.InProgress].Any(t => t.TaskId == taskInfo1.TaskId));
            Assert.IsFalse(this.Repository.GetActive().Any(t => t.TaskId == taskInfo1.TaskId));
            Assert.IsFalse(this.Repository.GetFailed().Any(t => t.TaskId == taskInfo1.TaskId));
            Assert.IsFalse(this.Repository.GetArchive().Any(t => t.TaskId == taskInfo1.TaskId));
            Assert.IsTrue(this.Repository.ReservePollingQueueTasks("Test", 1).Any(t => t.TaskId == taskInfo1.TaskId));
        }
        public void StartTaskCanceled()
        {
            ITaskRuntimeInfo taskInfo = this.Repository.TaskRuntimeInfo.Add();

            ITask task = new FakeTask();

            this.Repository.Tasks.Add(taskInfo.TaskId, task);

            using (FakeTaskWorker worker = new FakeTaskWorker())
            {
                this.TaskWorkerFactory.PredefineResult(worker, f => f.CreateTaskWorker(task));

                this.Repository.TaskRuntimeInfo.RequestCancel(taskInfo.TaskId, DateTime.UtcNow);

                this.TaskWorkerBootstrap.StartTask(taskInfo.TaskId);
            }
        }
        private void StartTaskCompleted(Action <Guid> completeTask)
        {
            ITaskRuntimeInfo taskInfo = this.Repository.TaskRuntimeInfo.Create();

            this.Repository.TaskRuntimeInfo.Add(taskInfo);

            ITask task = new FakeTask();

            this.Repository.Tasks.Add(taskInfo.TaskId, task);

            using (FakeTaskWorker worker = new FakeTaskWorker())
            {
                this.TaskWorkerFactory.PredefineResult(worker, f => f.CreateTaskWorker(task));
            }

            completeTask(taskInfo.TaskId);

            this.TaskWorkerBootstrap.StartTask(taskInfo.TaskId);
        }