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