示例#1
0
        public async Task ItExecutesTimespanRecurringTasksAccordingToTheirSchedules()
        {
            const int numberOfTasks              = 10;
            const int timeInterval               = 1000;
            const int testIntervals              = 10;
            const int numberOfSchedulerThreads   = 4;
            const int precisionAllowanceFactorMs = 500;

            ThreadPool.SetMinThreads(numberOfSchedulerThreads * 4, 200);

            var taskQueue     = TaskQueueTestFixture.UniqueRedisTaskQueue();
            var taskScheduler = new TaskScheduler(taskQueue);

            var canceled           = false;
            var taskSchedulerTasks = new List <Task>();
            var taskRunnerTasks    = new List <Task>();

            for (var s = 0; s < numberOfSchedulerThreads; ++s)
            {
                taskSchedulerTasks.Add(Task.Run(async() => {
                    var inThreadTaskScheduler = new TaskScheduler(taskQueue);
                    while (!canceled)
                    {
                        await inThreadTaskScheduler.Tick(forceRunPromotion: true);
                    }
                }));

                taskRunnerTasks.Add(Task.Run(async() => {
                    while (!canceled)
                    {
                        await taskQueue.ExecuteNext();
                    }
                }));
            }

            var tasks = new List <(RecurringTask, string, string)>();

            System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
            for (var i = 0; i < numberOfTasks; ++i)
            {
                var semaphoreFile = Path.GetTempFileName();
                File.Delete(semaphoreFile);
                semaphoreFile = semaphoreFile + Guid.NewGuid().ToString();

                var semaphoreValue = Guid.NewGuid().ToString();

                var recurringTask = await taskScheduler.AddRecurringTask(
                    () => TaskQueueTestFixture.WriteSemaphoreValue(semaphoreFile, semaphoreValue),
                    TimeSpan.FromMilliseconds(timeInterval),
                    Guid.NewGuid().ToString());

                tasks.Add((recurringTask, semaphoreFile, semaphoreValue));
            }

            _testOutputHelper.WriteLine("Test Add: " + sw.ElapsedMilliseconds.ToString());

            Thread.Sleep(110);

            for (var i = 0; i < testIntervals; ++i)
            {
                Thread.Sleep(timeInterval);

                foreach (var task in tasks)
                {
                    var diff = (DateTime.UtcNow.ToUnixTimeMilliseconds()
                                - task.Item1.StartTime.ToUnixTimeMilliseconds());
                    var elapsedIntervalsMax =
                        diff / timeInterval;

                    var elapsedIntervalsMin = (diff % timeInterval) <= precisionAllowanceFactorMs
                        ? elapsedIntervalsMax - 1
                        : elapsedIntervalsMax;

                    _testOutputHelper.WriteLine(diff.ToString());

                    elapsedIntervalsMax.Should().BeGreaterThan(i);

                    var expectedStringMax = "";
                    for (var e = 0; e < elapsedIntervalsMax; ++e)
                    {
                        expectedStringMax += task.Item3;
                    }

                    var expectedStringMin = "";
                    for (var e = 0; e < elapsedIntervalsMin; ++e)
                    {
                        expectedStringMin += task.Item3;
                    }

                    File.Exists(task.Item2).Should().BeTrue(elapsedIntervalsMax.ToString());

                    var fileText = File.ReadAllText(task.Item2);
                    if (fileText != expectedStringMax)
                    {
                        fileText.Should().Be(expectedStringMin);
                    }
                }
            }

            canceled = true;
            await Task.WhenAll(taskSchedulerTasks);

            await Task.WhenAll(taskRunnerTasks);
        }