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);
        }
Exemple #2
0
        public void NoMaxTasks()
        {
            ITaskProcessorConfiguration configuration = AppConfigConfigurationUnitTests.GetTaskProcessorConfiguration("NoMaxTasks");

            Assert.IsNull(configuration.Tasks.MaxWorkers);

            ITaskJobConfiguration jobConfig = configuration.Tasks[typeof(IFakeTask)];

            Assert.IsNotNull(jobConfig);

            Assert.AreEqual(typeof(IFakeTask), jobConfig.TaskType);

            Assert.IsNull(jobConfig.MaxWorkers);
        }
        public void AddCopy(ITaskJobConfiguration taskJob)
        {
            if (taskJob == null)
            {
                throw new ArgumentNullException("taskJob");
            }

            if (this.taskJobs.ContainsKey(taskJob.TaskType))
            {
                throw new ArgumentException("Task job configuration for type '{0}' already exists.".FormatInvariant(taskJob.TaskType), "taskJob");
            }

            this.taskJobs.Add(taskJob.TaskType, (FakeTaskJobConfiguration)taskJob);
        }
        /// <inheritdoc />
        public void AddCopy(ITaskJobConfiguration source)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }

            if (this.taskJobs.ContainsKey(source.TaskType))
            {
                throw new ArgumentException("Task job configuration for type '{0}' already exists.".FormatInvariant(source.TaskType), "source");
            }

            this.taskJobs.Add(source.TaskType, new RedisTaskJobConfiguration(source));
        }
        private static void Deserialize(IReadOnlyDictionary <string, string> values, ITaskJobsConfiguration result, string prefix)
        {
            if (!string.IsNullOrEmpty(prefix) && !prefix.EndsWith(".", StringComparison.Ordinal))
            {
                prefix = prefix + ".";
            }

            result.MaxWorkers = RedisConverter.ParseIntegerOrNull(values[prefix + "MaxTasks"]);

            foreach (KeyValuePair <string, string> pair in values.Where(v => v.Key.StartsWith(prefix, StringComparison.Ordinal) && v.Key.EndsWith(".TaskType", StringComparison.Ordinal)))
            {
                Type taskType = RedisConverter.ParseType(pair.Value);

                ITaskJobConfiguration jobConfig = result.Add(taskType);

                string key = string.Concat(prefix, taskType.Name, ".MaxWorkers");

                jobConfig.MaxWorkers = RedisConverter.ParseIntegerOrNull(values[key]);
            }
        }
Exemple #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="RedisTaskJobConfiguration"/> class by copying the properties of another instance.
 /// </summary>
 /// <param name="source">The instance whose properties to copy.</param>
 internal RedisTaskJobConfiguration(ITaskJobConfiguration source)
 {
     this.taskType   = source.TaskType;
     this.maxWorkers = source.MaxWorkers;
 }
        /// <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++;
            }
        }
 /// <inheritdoc />
 void ITaskJobsConfiguration.AddCopy(ITaskJobConfiguration taskJob)
 {
     throw new NotSupportedException();
 }