예제 #1
0
        public async Task ItAllowsForRecurringTasksTaskInfoToBeChanged()
        {
            var taskName      = Guid.NewGuid().ToString();
            var taskQueue     = TaskQueueTestFixture.UniqueRedisTaskQueue();
            var taskScheduler = new TaskScheduler(taskQueue);

            var recurringTask = await taskScheduler.AddRecurringTask(() => TaskQueueTestFixture.WriteSemaphore("afile"),
                                                                     $"*/{IntervalSeconds} * * * * *", taskName);

            var fetchedRecurringTask = await taskScheduler.GetRecurringTask(recurringTask.TaskKey);

            fetchedRecurringTask.TaskInfo.MethodName.Should().Be("WriteSemaphore");
            fetchedRecurringTask.Interval.Should().BeNull();
            fetchedRecurringTask.Crontab.Should().Be($"*/{IntervalSeconds} * * * * *");
            fetchedRecurringTask.TaskInfo.Args[0].Should().Be("afile");

            // Different Argument
            await taskScheduler.AddRecurringTask(() => TaskQueueTestFixture.WriteSemaphore("bfile"),
                                                 $"*/{IntervalSeconds} * * * * *", taskName);

            fetchedRecurringTask = await taskScheduler.GetRecurringTask(recurringTask.TaskKey);

            fetchedRecurringTask.TaskInfo.MethodName.Should().Be("WriteSemaphore");
            fetchedRecurringTask.Interval.Should().BeNull();
            fetchedRecurringTask.Crontab.Should().Be($"*/{IntervalSeconds} * * * * *");
            fetchedRecurringTask.TaskInfo.Args[0].Should().Be("bfile");

            // Different Interval
            await taskScheduler.AddRecurringTask(() => TaskQueueTestFixture.WriteSemaphore("bfile"),
                                                 TimeSpan.FromSeconds(IntervalSeconds), taskName);

            fetchedRecurringTask = await taskScheduler.GetRecurringTask(recurringTask.TaskKey);

            fetchedRecurringTask.TaskInfo.MethodName.Should().Be("WriteSemaphore");
            fetchedRecurringTask.Interval.Should().Be(TimeSpan.FromSeconds(IntervalSeconds));
            fetchedRecurringTask.Crontab.Should().BeNull();
            fetchedRecurringTask.TaskInfo.Args[0].Should().Be("bfile");

            // Different Target Method
            await taskScheduler.AddRecurringTask(() => TaskQueueTestFixture.WriteSemaphoreValue("bfile", "avalue"),
                                                 TimeSpan.FromSeconds(IntervalSeconds), taskName);

            fetchedRecurringTask = await taskScheduler.GetRecurringTask(recurringTask.TaskKey);

            fetchedRecurringTask.TaskInfo.MethodName.Should().Be("WriteSemaphoreValue");
            fetchedRecurringTask.Interval.Should().Be(TimeSpan.FromSeconds(IntervalSeconds));
            fetchedRecurringTask.Crontab.Should().BeNull();
            fetchedRecurringTask.TaskInfo.Args[0].Should().Be("bfile");
            fetchedRecurringTask.TaskInfo.Args[1].Should().Be("avalue");
        }
예제 #2
0
        public void Test1()
        {
            var schedualler = new TaskScheduler();
            var cts         = new CancellationTokenSource();

            schedualler.AddRecurringTask(() => { this.output.WriteLine(DateTime.Now.ToString("T")); }, TimeSpan.FromSeconds(1), cts.Token);
            Thread.Sleep(5000);
            cts.Cancel();
        }
예제 #3
0
        public async Task ItDoesNotOverwriteOriginalRecurringTaskWhenDuplicatesAreAdded()
        {
            var taskName      = Guid.NewGuid().ToString();
            var taskQueue     = TaskQueueTestFixture.UniqueRedisTaskQueue();
            var taskScheduler = new TaskScheduler(taskQueue);

            var originalRecurringTask = await taskScheduler.AddRecurringTask(() => TaskQueueTestFixture.WriteSemaphore("a"),
                                                                             TimeSpan.FromSeconds(IntervalSeconds), taskName);

            var duplicateRecurringTask = await taskScheduler.AddRecurringTask(() => TaskQueueTestFixture.WriteSemaphore("a"),
                                                                              TimeSpan.FromSeconds(IntervalSeconds), taskName);

            originalRecurringTask.Should().NotBeNull();
            duplicateRecurringTask.Should().BeNull();

            var recurringTask = await taskScheduler.GetRecurringTask(originalRecurringTask.TaskKey);

            recurringTask.StartTime.Should().Be(originalRecurringTask.StartTime);
        }
예제 #4
0
        public async Task ItExecutesTasksOnlyOnceWhenUsingMultipleConsumers(string taskType)
        {
            var semaphoreFile = Path.GetTempFileName();

            File.Delete(semaphoreFile);
            File.Create(semaphoreFile).Close();

            var intervalSeconds = 5;
            var taskQueue       = TaskQueueTestFixture.UniqueRedisTaskQueue();

            var schedulingTaskScheduler = new TaskScheduler(taskQueue);

            var taskSchedulers = new[]
            {
                new TaskScheduler(taskQueue),
                new TaskScheduler(taskQueue),
                new TaskScheduler(taskQueue),
                new TaskScheduler(taskQueue),
            };

            if (taskType == "scheduled")
            {
                await schedulingTaskScheduler.AddScheduledTask(() => TaskQueueTestFixture.WriteSemaphore(semaphoreFile),
                                                               TimeSpan.FromSeconds(intervalSeconds));
            }

            if (taskType == "recurring")
            {
                await schedulingTaskScheduler.AddRecurringTask(() => TaskQueueTestFixture.WriteSemaphore(semaphoreFile),
                                                               TimeSpan.FromSeconds(intervalSeconds), RandomTaskName);
            }

            Thread.Sleep(((intervalSeconds) * 1000) + 50);

            // Ran only once
            await Task.WhenAll(
                taskSchedulers.Select(
                    taskScheduler =>
                    Task.Run(async() =>
            {
                await taskScheduler.Tick();
                await taskQueue.ExecuteNext();
            })));

            File.Exists(semaphoreFile).Should().Be(true);
            File.ReadAllText(semaphoreFile).Should().Be(TaskQueueTestFixture.SemaphoreText);


            // Ran only twice (or once if scheduled)
            Thread.Sleep(((intervalSeconds) * 1000) + 50);
            await Task.WhenAll(
                taskSchedulers.Select(
                    taskScheduler =>
                    Task.Run(async() =>
            {
                await taskScheduler.Tick();
                await taskQueue.ExecuteNext();
            })));

            if (taskType == "recurring")
            {
                File.ReadAllText(semaphoreFile).Should()
                .Be(TaskQueueTestFixture.SemaphoreText + TaskQueueTestFixture.SemaphoreText);
            }
            if (taskType == "scheduled")
            {
                File.ReadAllText(semaphoreFile).Should()
                .Be(TaskQueueTestFixture.SemaphoreText);
            }
        }
예제 #5
0
        public async Task ItExecutesCrontabRecurringTasksAccordingToTheirSchedules()
        {
            const int numberOfTasks              = 10;
            const int timeInterval               = 1000;
            const int testIntervals              = 10;
            const int numberOfSchedulerThreads   = 4;
            const int precisionAllowanceFactorMs = 800;

            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)>();

            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),
                    $"*/{timeInterval / 1000} * * * * *",
                    Guid.NewGuid().ToString());

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

            var synchronizationFactor =
                DateTime.UtcNow.ToUnixTimeMilliseconds() - DateTime.UtcNow.ToUnixTimeSeconds() * 1000;

            Thread.Sleep((int)synchronizationFactor + 100);

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

                foreach (var task in tasks)
                {
                    var diff = DateTime.UtcNow.ToUnixTimeMilliseconds()
                               - (task.Item1.FirstRunTime.ToUnixTimeMilliseconds() - timeInterval);
                    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);
        }