Example #1
0
        public void UpdateTaskProcessorRuntimeInfo()
        {
            ITaskProcessorRuntimeInfo processorInfo = this.Repository.Create(Guid.NewGuid(), "Test");

            processorInfo.Configuration.Tasks.Add(typeof(IFakeTask));

            this.Repository.Add(processorInfo);

            processorInfo.Configuration.Tasks.MaxWorkers = 100;

            processorInfo.Configuration.Tasks.Remove(typeof(IFakeTask));

            processorInfo.Configuration.Tasks.Add(typeof(IFakeTask2)).MaxWorkers = 10;

            processorInfo.Configuration.PollingJobs.Add(typeof(FakePollingJob));

            processorInfo.Configuration.PollingJobs[typeof(FakePollingJob)].PollInterval = TimeSpan.FromMinutes(1);
            processorInfo.Configuration.PollingJobs[typeof(FakePollingJob)].IsMaster     = true;

            this.Repository.Update(processorInfo);

            processorInfo = this.Repository.GetById(processorInfo.TaskProcessorId);

            Assert.AreEqual(100, processorInfo.Configuration.Tasks.MaxWorkers);
            Assert.AreEqual(1, processorInfo.Configuration.Tasks.Count());
            Assert.AreEqual(10, processorInfo.Configuration.Tasks[typeof(IFakeTask2)].MaxWorkers);

            Assert.AreEqual(TimeSpan.FromMinutes(1), processorInfo.Configuration.PollingJobs[typeof(FakePollingJob)].PollInterval);

            Assert.IsTrue(processorInfo.Configuration.PollingJobs[typeof(FakePollingJob)].IsMaster);
            Assert.IsFalse(processorInfo.Configuration.PollingJobs[typeof(FakePollingJob)].IsActive);
        }
Example #2
0
        public void GetAllTaskProcessorRuntimeInfo()
        {
            ITaskProcessorRuntimeInfo processorInfo1 = this.Repository.Create(Guid.NewGuid(), "First");

            this.Repository.Add(processorInfo1);

            ITaskProcessorRuntimeInfo processorInfo2 = this.Repository.Create(Guid.NewGuid(), "Second");

            this.Repository.Add(processorInfo2);

            ITaskProcessorRuntimeInfo[] processorInfos = this.Repository.GetAll().ToArray();

            ITaskProcessorRuntimeInfo processorInfo11 = processorInfos.FirstOrDefault(p => p.TaskProcessorId == processorInfo1.TaskProcessorId);

            Assert.IsNotNull(processorInfo11);

            Assert.AreEqual(processorInfo1.TaskProcessorId, processorInfo11.TaskProcessorId);
            Assert.AreEqual(processorInfo1.MachineName, processorInfo11.MachineName);

            ITaskProcessorRuntimeInfo processorInfo22 = processorInfos.FirstOrDefault(p => p.TaskProcessorId == processorInfo2.TaskProcessorId);

            Assert.IsNotNull(processorInfo11);

            Assert.AreEqual(processorInfo2.TaskProcessorId, processorInfo22.TaskProcessorId);
            Assert.AreEqual(processorInfo2.MachineName, processorInfo22.MachineName);
        }
        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);
        }
Example #4
0
        /// <inheritdoc />
        public void Update(ITaskProcessorRuntimeInfo taskProcessorInfo)
        {
            if (taskProcessorInfo == null)
            {
                throw new ArgumentNullException("taskProcessorInfo");
            }

            Trace.WriteLine("ENTER: Updating {0} ...".FormatInvariant(taskProcessorInfo));

            string entityKey = RedisTaskProcessorRuntimeInfoRepository.GetEntityKey(taskProcessorInfo.TaskProcessorId);

            IReadOnlyDictionary <string, string> values = RedisTaskProcessorRuntimeInfoRepository.Serialize(taskProcessorInfo);

            using (IRedisTransaction transaction = this.provider.CreateTransaction())
            {
                transaction.RemoveKey(entityKey);

                transaction.SetHashValues(entityKey, values);

                if (this.expiration < TimeSpan.MaxValue)
                {
                    transaction.ExpireKeyIn(entityKey, this.expiration);
                }

                transaction.Commit();
            }

            Trace.WriteLine("EXIT: {0} updated.".FormatInvariant(taskProcessorInfo));
        }
Example #5
0
        public void PollingJobsConfiguration()
        {
            FakeTaskProcessorRuntimeInfo processorInfo1 = new FakeTaskProcessorRuntimeInfo()
            {
                TaskProcessorId = Guid.NewGuid(),

                Configuration = new FakeTaskProcessorConfiguration()
            };

            processorInfo1.Configuration.PollingJobs.Add(new FakePollingJobConfiguration()
            {
                ImplementationType = typeof(FakePollingJob),
                PollInterval       = TimeSpan.FromMinutes(1),
                IsMaster           = true
            });

            processorInfo1.Configuration.PollingJobs.Add(new FakePollingJobConfiguration()
            {
                ImplementationType = typeof(FakePollingJob2),
                PollInterval       = TimeSpan.FromMinutes(2),
                IsActive           = true
            });

            processorInfo1.Configuration.PollingJobs.Add(new FakePollingJobConfiguration()
            {
                ImplementationType = typeof(FakePollingJob3),
                PollInterval       = TimeSpan.FromMinutes(3),
                IsConcurrent       = true
            });

            this.Repository.Add(processorInfo1);

            ITaskProcessorRuntimeInfo processorInfo2 = this.Repository.GetById(processorInfo1.TaskProcessorId);

            Assert.AreEqual(3, processorInfo2.Configuration.PollingJobs.Count());

            IPollingJobConfiguration queue1 = processorInfo2.Configuration.PollingJobs.First(q => q.ImplementationType == typeof(FakePollingJob));

            Assert.AreEqual(TimeSpan.FromMinutes(1), queue1.PollInterval);
            Assert.IsTrue(queue1.IsMaster);
            Assert.IsFalse(queue1.IsActive);
            Assert.IsFalse(queue1.IsConcurrent);

            IPollingJobConfiguration queue2 = processorInfo2.Configuration.PollingJobs.First(q => q.ImplementationType == typeof(FakePollingJob2));

            Assert.AreEqual(TimeSpan.FromMinutes(2), queue2.PollInterval);
            Assert.IsFalse(queue2.IsMaster);
            Assert.IsTrue(queue2.IsActive);
            Assert.IsFalse(queue2.IsConcurrent);

            IPollingJobConfiguration queue3 = processorInfo2.Configuration.PollingJobs.First(q => q.ImplementationType == typeof(FakePollingJob3));

            Assert.AreEqual(TimeSpan.FromMinutes(3), queue3.PollInterval);
            Assert.IsFalse(queue3.IsMaster);
            Assert.IsFalse(queue3.IsActive);
            Assert.IsTrue(queue3.IsConcurrent);
        }
Example #6
0
        public void PollingQueuesConfiguration()
        {
            FakeTaskProcessorRuntimeInfo processorInfo1 = new FakeTaskProcessorRuntimeInfo()
            {
                TaskProcessorId = Guid.NewGuid(),
                Configuration   = new FakeTaskProcessorConfiguration()
            };

            processorInfo1.Configuration.PollingQueues.Add(new FakePollingQueueConfiguration()
            {
                Key          = "A",
                PollInterval = TimeSpan.FromMinutes(1),
                IsMaster     = true
            });

            processorInfo1.Configuration.PollingQueues.Add(new FakePollingQueueConfiguration()
            {
                Key          = "B",
                PollInterval = TimeSpan.FromMinutes(2),
                IsActive     = true
            });

            processorInfo1.Configuration.PollingQueues.Add(new FakePollingQueueConfiguration()
            {
                Key          = "C",
                PollInterval = TimeSpan.FromMinutes(3),
                IsConcurrent = true
            });

            this.Repository.Add(processorInfo1);

            ITaskProcessorRuntimeInfo processorInfo2 = this.Repository.GetById(processorInfo1.TaskProcessorId);

            Assert.AreEqual(3, processorInfo2.Configuration.PollingQueues.Count());

            ITaskProcessorPollingQueueConfiguration queue = processorInfo2.Configuration.PollingQueues.First(q => q.Key == "A");

            Assert.AreEqual(TimeSpan.FromMinutes(1), queue.PollInterval);
            Assert.IsTrue(queue.IsMaster);
            Assert.IsFalse(queue.IsActive);
            Assert.IsFalse(queue.IsConcurrent);

            queue = processorInfo2.Configuration.PollingQueues.First(q => q.Key == "B");

            Assert.AreEqual(TimeSpan.FromMinutes(2), queue.PollInterval);
            Assert.IsFalse(queue.IsMaster);
            Assert.IsTrue(queue.IsActive);
            Assert.IsFalse(queue.IsConcurrent);

            queue = processorInfo2.Configuration.PollingQueues.First(q => q.Key == "C");

            Assert.AreEqual(TimeSpan.FromMinutes(3), queue.PollInterval);
            Assert.IsFalse(queue.IsMaster);
            Assert.IsFalse(queue.IsActive);
            Assert.IsTrue(queue.IsConcurrent);
        }
        public void Update(ITaskProcessorRuntimeInfo taskProcessorInfo)
        {
            if (taskProcessorInfo == null)
            {
                throw new ArgumentNullException("taskProcessorInfo");
            }

            this.RecordMethodCall(taskProcessorInfo);

            this.taskProcessors[taskProcessorInfo.TaskProcessorId] = (FakeTaskProcessorRuntimeInfo)taskProcessorInfo;
        }
Example #8
0
        private static IReadOnlyDictionary <string, string> Serialize(ITaskProcessorRuntimeInfo taskProcessorInfo)
        {
            Dictionary <string, string> result = new Dictionary <string, string>()
            {
                { "Id", RedisConverter.ToString(taskProcessorInfo.TaskProcessorId) },
                { "MachineName", RedisConverter.ToString(taskProcessorInfo.MachineName) }
            };

            RedisTaskProcessorConfigurationRepository.Serialize(taskProcessorInfo.Configuration, result, "Configuration");

            return(result);
        }
Example #9
0
        public void ExpirationAdd()
        {
            this.Repository.Expiration = TimeSpan.FromSeconds(0.5);

            ITaskProcessorRuntimeInfo processorInfo = this.Repository.Create(Guid.NewGuid(), "Test");

            this.Repository.Add(processorInfo);

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

            this.AssertTaskProcessorInfoIsNotAvailable(processorInfo.TaskProcessorId);
        }
Example #10
0
        private void OnTaskProcessorStateChanged(object sender, TaskProcessorStateEventArgs e)
        {
            switch (e.TaskProcessorState)
            {
            case TaskProcessorState.Active:
            {
                ITaskProcessorRuntimeInfo processorInfo = this.taskProcessorFacade.GetTaskProcessorRuntimeInfo(e.TaskProcessorId);

                if (processorInfo == null)
                {
                    return;
                }

                TaskProcessorViewModel processorViewModel = new TaskProcessorViewModel(processorInfo.TaskProcessorId, processorInfo.MachineName)
                {
                    State = TaskProcessorState.Active
                };

                Guid?masterId = this.taskProcessorFacade.GetMasterTaskProcessorId();

                if (masterId.HasValue && masterId.Value == e.TaskProcessorId)
                {
                    processorViewModel.IsMaster = true;
                }

                App.Current.Dispatcher.InvokeAsync(() =>
                    {
                        this.taskProcessors.Add(processorViewModel);
                    });
            }

            break;

            case TaskProcessorState.Stopping:
            case TaskProcessorState.Inactive:
            {
                TaskProcessorViewModel processorViewModel = this.taskProcessors.FirstOrDefault(p => p.TaskProcessorId == e.TaskProcessorId);

                if (processorViewModel == null)
                {
                    return;
                }

                App.Current.Dispatcher.InvokeAsync(() =>
                    {
                        processorViewModel.State = e.TaskProcessorState;
                    });
            }

            break;
            }
        }
Example #11
0
        public void CreateTaskProcessorRuntimeInfo()
        {
            Guid processorId = Guid.NewGuid();

            ITaskProcessorRuntimeInfo processorInfo = this.Repository.Create(processorId, "Test");

            Assert.AreEqual(processorId, processorInfo.TaskProcessorId);
            Assert.AreEqual("Test", processorInfo.MachineName);
            Assert.IsNotNull(processorInfo.Configuration);
            Assert.IsNotNull(processorInfo.Configuration.Tasks);
            Assert.IsNull(processorInfo.Configuration.Tasks.MaxWorkers);
            Assert.IsFalse(processorInfo.Configuration.Tasks.Any());
        }
        /// <inheritdoc />
        public void UpdateTaskProcessorRuntimeInfo(ITaskProcessorRuntimeInfo taskProcessorInfo)
        {
            if (taskProcessorInfo == null)
            {
                throw new ArgumentNullException("taskProcessorInfo");
            }

            Trace.WriteLine("ENTER: Updating {0} ...".FormatInvariant(taskProcessorInfo));

            this.repository.TaskProcessorRuntimeInfo.Update(taskProcessorInfo);

            Trace.WriteLine("EXIT: {0} updated.".FormatInvariant(taskProcessorInfo));
        }
        public void Add(ITaskProcessorRuntimeInfo taskProcessorInfo)
        {
            if (taskProcessorInfo == null)
            {
                throw new ArgumentNullException("taskProcessorInfo");
            }

            this.RecordMethodCall(taskProcessorInfo);

            FakeTaskProcessorRuntimeInfo fakeProcessor = (FakeTaskProcessorRuntimeInfo)taskProcessorInfo;

            fakeProcessor.ExpireAt = DateTime.Now + this.Expiration;

            this.taskProcessors.Add(taskProcessorInfo.TaskProcessorId, fakeProcessor);
        }
Example #14
0
        private void OnTaskProcessorConfigurationClick(object sender, RoutedEventArgs e)
        {
            TaskProcessorViewModel processorViewModel = (TaskProcessorViewModel)((FrameworkElement)sender).DataContext;

            ITaskProcessorRuntimeInfo processorInfo = this.ViewModel.TaskProcessorFacade.GetTaskProcessorRuntimeInfo(processorViewModel.TaskProcessorId);

            ConfigurationWindow dialog = new ConfigurationWindow(processorInfo.Configuration)
            {
                Title          = "Task Processor Configuration",
                SaveButtonText = "Save"
            };

            if (dialog.ShowDialog() == true)
            {
                this.ViewModel.TaskProcessorFacade.UpdateTaskProcessorRuntimeInfo(processorInfo);
            }
        }
Example #15
0
        public void GetTaskProcessorRuntimeInfoById2()
        {
            ITaskProcessorRuntimeInfo processorInfo1 = this.Repository.Create(Guid.NewGuid(), "Test");

            processorInfo1.Configuration.Tasks.Add(typeof(IFakeTask));

            this.Repository.Add(processorInfo1);

            ITaskProcessorRuntimeInfo processorInfo2 = this.Repository.GetById(processorInfo1.TaskProcessorId);

            Assert.IsNotNull(processorInfo2);

            Assert.AreEqual(processorInfo1.TaskProcessorId, processorInfo2.TaskProcessorId);
            Assert.AreEqual(processorInfo1.MachineName, processorInfo2.MachineName);

            Assert.IsNull(processorInfo2.Configuration.Tasks.MaxWorkers);
            Assert.AreEqual(1, processorInfo2.Configuration.Tasks.Count());
            Assert.IsNull(processorInfo2.Configuration.Tasks[typeof(IFakeTask)].MaxWorkers);
        }
Example #16
0
        public void TaskRequestedAssignToSecondProcessor()
        {
            Guid taskProcessorId1 = Guid.NewGuid();
            Guid taskProcessorId2 = Guid.NewGuid();

            ITaskProcessorRuntimeInfo firstProcessor  = this.Repository.TaskProcessorRuntimeInfo.Create(taskProcessorId1, "First");
            ITaskProcessorRuntimeInfo secondProcessor = this.Repository.TaskProcessorRuntimeInfo.Create(taskProcessorId2, "Second");

            this.Repository.TaskProcessorRuntimeInfo.Add(firstProcessor);
            this.Repository.TaskProcessorRuntimeInfo.Add(secondProcessor);

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

            this.Repository.TaskRuntimeInfo.Add(pendingTaskInfo);

            this.TaskDistributor.PredefineResult(
                new ITaskProcessorRuntimeInfo[] { firstProcessor, secondProcessor },
                d => d.ChooseProcessorForTask(pendingTaskInfo));

            this.MasterCommandsProcessor.AssignTaskTimeout = TimeSpan.FromSeconds(1);

            this.MessageBus.Tasks.NotifyTaskSubmitted(pendingTaskInfo.TaskId, DateTime.UtcNow, false);

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

            this.TaskDistributor.AssertMethodCallWithArguments(d => d.ChooseProcessorForTask(pendingTaskInfo));

            this.MessageBus.Tasks.AssertMethodCallWithArguments(mb => mb.NotifyTaskAssigned(pendingTaskInfo.TaskId, taskProcessorId1));
            this.MessageBus.Tasks.AssertMethodCallWithArguments(mb => mb.NotifyTaskAssigned(pendingTaskInfo.TaskId, taskProcessorId2));

            this.MessageBus.Tasks.AssertNoMethodCall(mb => mb.NotifyTaskAssigned(Guid.Empty, Guid.Empty));

            this.MessageBus.Tasks.NotifyTaskStarted(pendingTaskInfo.TaskId, taskProcessorId2, DateTime.UtcNow);

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

            Assert.IsFalse(this.MessageBus.MasterCommands.OfType <TaskSubmittedMasterCommand>().Any(c => c.TaskId == pendingTaskInfo.TaskId));

            pendingTaskInfo = this.Repository.TaskRuntimeInfo.GetById(pendingTaskInfo.TaskId);

            Assert.AreEqual(taskProcessorId2, pendingTaskInfo.TaskProcessorId);
        }
Example #17
0
        private void InvalidPollingJobInterval(TimeSpan interval)
        {
            FakeTaskProcessorRuntimeInfo processorInfo1 = new FakeTaskProcessorRuntimeInfo()
            {
                TaskProcessorId = Guid.NewGuid(),
                Configuration   = new FakeTaskProcessorConfiguration()
            };

            processorInfo1.Configuration.PollingJobs.Add(new FakePollingJobConfiguration()
            {
                ImplementationType = typeof(FakePollingJob),
                PollInterval       = TimeSpan.FromMinutes(1)
            });

            this.Repository.Add(processorInfo1);

            ITaskProcessorRuntimeInfo processorInfo2 = this.Repository.GetById(processorInfo1.TaskProcessorId);

            IPollingJobConfiguration queue1 = processorInfo2.Configuration.PollingJobs.First(q => q.ImplementationType == typeof(FakePollingJob));

            queue1.PollInterval = interval;
        }
 public void UpdateTaskProcessorRuntimeInfo(ITaskProcessorRuntimeInfo taskProcessorInfo)
 {
     throw new NotImplementedException();
 }
Example #19
0
        private void AssignTasksToProcessorTest(Guid taskProcessorId, Action callback)
        {
            this.MasterCommandsProcessor.IsActive = false;

            ITaskProcessorRuntimeInfo processorInfo = this.Repository.TaskProcessorRuntimeInfo.Create(taskProcessorId, "Test");

            this.Repository.TaskProcessorRuntimeInfo.Add(processorInfo);

            ITaskRuntimeInfo pendingTaskInfo1 = new FakeTaskRuntimeInfo()
            {
                TaskId       = Guid.NewGuid(),
                SubmittedUtc = DateTime.UtcNow
            };

            ITaskRuntimeInfo pendingTaskInfo2 = new FakeTaskRuntimeInfo()
            {
                TaskId       = Guid.NewGuid(),
                SubmittedUtc = DateTime.UtcNow
            };

            ITaskRuntimeInfo activeTaskInfo1 = new FakeTaskRuntimeInfo()
            {
                TaskId       = Guid.NewGuid(),
                SubmittedUtc = DateTime.UtcNow
            };

            ITaskRuntimeInfo activeTaskInfo2 = new FakeTaskRuntimeInfo()
            {
                TaskId       = Guid.NewGuid(),
                SubmittedUtc = DateTime.UtcNow
            };

            this.Repository.TaskRuntimeInfo.Add(pendingTaskInfo1);
            this.Repository.TaskRuntimeInfo.Add(pendingTaskInfo2);
            this.Repository.TaskRuntimeInfo.Add(activeTaskInfo1);
            this.Repository.TaskRuntimeInfo.Add(activeTaskInfo2);

            this.Repository.TaskRuntimeInfo.Start(activeTaskInfo1.TaskId, Guid.Empty, DateTime.UtcNow);
            this.Repository.TaskRuntimeInfo.Start(activeTaskInfo2.TaskId, Guid.Empty, DateTime.UtcNow);

            this.TaskDistributor.PredefineResult(
                new ITaskRuntimeInfo[] { pendingTaskInfo1, pendingTaskInfo2 },
                d => d.ChooseNextTasksForProcessor(processorInfo.TaskProcessorId));

            this.MasterCommandsProcessor.AssignTaskTimeout = TimeSpan.FromSeconds(0.5);

            this.MasterCommandsProcessor.IsActive = true;

            callback();

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

            this.TaskDistributor.AssertMethodCallOnceWithArguments(d => d.ChooseNextTasksForProcessor(processorInfo.TaskProcessorId));

            foreach (ITaskRuntimeInfo taskInfo in new ITaskRuntimeInfo[] { pendingTaskInfo1, pendingTaskInfo2 })
            {
                this.MessageBus.Tasks.AssertMethodCallWithArguments(mb => mb.NotifyTaskAssigned(taskInfo.TaskId, taskProcessorId));
            }

            this.MessageBus.Tasks.AssertNoMethodCall(mb => mb.NotifyTaskAssigned(Guid.Empty, Guid.Empty));
        }
        /// <inheritdoc />
        public IEnumerable <ITaskRuntimeInfo> ChooseNextTasksForProcessor(Guid taskProcessorId)
        {
            Trace.WriteLine("ENTER: Choosing next tasks to assign to processor '{0}' ...".FormatInvariant(taskProcessorId));

            ITaskProcessorRuntimeInfo taskProcessor = this.repository.TaskProcessorRuntimeInfo.GetById(taskProcessorId);

            if (taskProcessor == null)
            {
                Trace.WriteLine("EXIT: Processor '{0}' not found in configuration.".FormatInvariant(taskProcessorId));

                yield break;
            }

            var pendingAndActiveTasks = this.repository.TaskRuntimeInfo.GetPendingAndActive();

            IEnumerable <ITaskRuntimeInfo> pendingTasksInfo = pendingAndActiveTasks[TaskStatus.Pending];
            IEnumerable <ITaskRuntimeInfo> activeTasksInfo  = pendingAndActiveTasks[TaskStatus.InProgress];

            int?remainingTasksCount = null;

            if (taskProcessor.Configuration.Tasks.MaxWorkers.HasValue)
            {
                remainingTasksCount = taskProcessor.Configuration.Tasks.MaxWorkers.Value - activeTasksInfo.Count(t => t.TaskProcessorId == taskProcessor.TaskProcessorId);

                if (remainingTasksCount <= 0)
                {
                    Trace.WriteLine("EXIT: No tasks to assign because processor max workers threshold {0} is reached.".FormatInvariant(taskProcessor.Configuration.Tasks.MaxWorkers.Value));

                    yield break;
                }
            }

            Dictionary <Type, int> remainingTasksCountByTaskType = new Dictionary <Type, int>();

            Func <ITaskRuntimeInfo, bool> filterPredicate = pendingTaskInfo =>
            {
                Lazy <int> activeTasksCountByTaskType = new Lazy <int>(() => activeTasksInfo.Count(t => t.TaskType == pendingTaskInfo.TaskType));

                Lazy <int?> remainingTasksByTaskTypeValue = new Lazy <int?>(() => null);

                ITaskJobConfiguration processorTaskJobConfig = taskProcessor.Configuration.Tasks[pendingTaskInfo.TaskType];

                Lazy <int> activeProcessorTasksCountByTaskType = new Lazy <int>(() => activeTasksInfo.Count(t => (t.TaskType == pendingTaskInfo.TaskType) && (t.TaskProcessorId == taskProcessor.TaskProcessorId)));

                Lazy <int?> remainingProcessorTasksCountByTaskType = new Lazy <int?>(() => null);

                if ((processorTaskJobConfig != null) && processorTaskJobConfig.MaxWorkers.HasValue)
                {
                    if (activeProcessorTasksCountByTaskType.Value >= processorTaskJobConfig.MaxWorkers.Value)
                    {
                        return(false);
                    }

                    remainingProcessorTasksCountByTaskType = new Lazy <int?>(() => processorTaskJobConfig.MaxWorkers.Value - activeProcessorTasksCountByTaskType.Value);
                }

                if (!remainingTasksCountByTaskType.ContainsKey(pendingTaskInfo.TaskType))
                {
                    int?value = DefaultTaskDistributor.GetMinMaxWorkers(
                        remainingTasksByTaskTypeValue.Value,
                        remainingProcessorTasksCountByTaskType.Value);

                    if (value.HasValue)
                    {
                        remainingTasksCountByTaskType.Add(pendingTaskInfo.TaskType, value.Value);
                    }
                }

                return(true);
            };

            foreach (ITaskRuntimeInfo result in pendingTasksInfo
                     .OrderByDescending(t => (int)t.Priority)
                     .Where(filterPredicate))
            {
                int count;

                if (remainingTasksCountByTaskType.TryGetValue(result.TaskType, out count))
                {
                    if (count == 0)
                    {
                        continue;
                    }

                    remainingTasksCountByTaskType[result.TaskType] = count - 1;
                }

                yield return(result);

                if (remainingTasksCount == 1)
                {
                    yield break;
                }

                remainingTasksCount++;
            }
        }