/// <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))); }
/// <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++; } }