Beispiel #1
0
        public async Task AsyncFunc(string semaphoreFile)
        {
            // Wait to ensure async waiting is happening.
            await Task.Delay(1000);

            TaskQueueTestFixture.WriteSemaphoreValue(semaphoreFile, "async");
        }
Beispiel #2
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");
        }
Beispiel #3
0
        public void ArrayFunc3(int?[] nums, string semaphoreFile)
        {
            var str   = "";
            var first = true;

            foreach (var num in nums)
            {
                if (!first)
                {
                    str += ",";
                }
                str  += num?.ToString() ?? "null";
                first = false;
            }

            TaskQueueTestFixture.WriteSemaphoreValue(semaphoreFile, str);
        }
Beispiel #4
0
        public async Task ItExecutesImmediateAndScheduledTasksInOrder()
        {
            const int immediateTasks = 5;
            const int scheduledTasks = 20;

            const int scheduledTasksStart     = -100;
            const int scheduledTasksIncrement = 50;

            var taskQueue  = TaskQueueTestFixture.UniqueRedisTaskQueue();
            var taskClient = new TaskClient(taskQueue);

            var semaphoreFile = Path.GetTempFileName();

            File.Delete(semaphoreFile);
            File.Exists(semaphoreFile).Should().BeFalse();

            for (var i = 0; i < immediateTasks; ++i)
            {
                await taskClient.TaskQueue.Enqueue(() =>
                                                   TaskQueueTestFixture.WriteSemaphoreValue(semaphoreFile, (i + 1).ToString()));
            }

            for (var i = 0; i < scheduledTasks; ++i)
            {
                await taskClient.TaskScheduler.AddScheduledTask(
                    () => TaskQueueTestFixture.WriteSemaphoreValue(semaphoreFile, (immediateTasks + i + 1).ToString()),
                    TimeSpan.FromMilliseconds(scheduledTasksStart + (scheduledTasksIncrement *i)));
            }

            var task = Task.Run(async() => await taskClient.Listen());

            Thread.Sleep(scheduledTasks * scheduledTasksIncrement + 2000);

            var expectedFileContents = Enumerable
                                       .Range(1, immediateTasks + scheduledTasks)
                                       .Aggregate("", (acc, v) => acc + v.ToString());

            File.Exists(semaphoreFile).Should().BeTrue();
            File.ReadAllText(semaphoreFile).Should().Be(expectedFileContents);

            taskClient.CancelListen();
            await task;
        }
Beispiel #5
0
 public void ArrayFunc2(int[] nums, string semaphoreFile)
 {
     TaskQueueTestFixture.WriteSemaphoreValue(semaphoreFile, string.Join(",", nums));
 }
Beispiel #6
0
 public void TypeFunc(Type typeArg, string semaphoreFile)
 {
     TaskQueueTestFixture.WriteSemaphoreValue(semaphoreFile, typeArg?.ToString() ?? "null");
 }
Beispiel #7
0
 public void ExceptionFunc(Exception exc, string semaphoreFile)
 {
     TaskQueueTestFixture.WriteSemaphoreValue(semaphoreFile, exc);
 }
Beispiel #8
0
 public void ObjectFunc(object num, string semaphoreFile)
 {
     TaskQueueTestFixture.WriteSemaphoreValue(semaphoreFile, num);
 }
Beispiel #9
0
 public void StringFunc(string num, string semaphoreFile)
 {
     TaskQueueTestFixture.WriteSemaphoreValue(semaphoreFile, num);
 }
Beispiel #10
0
 public void DoubleFunc(double num, string semaphoreFile)
 {
     TaskQueueTestFixture.WriteSemaphoreValue(semaphoreFile, num);
 }
Beispiel #11
0
 public void BoolFunc(bool num, string semaphoreFile)
 {
     TaskQueueTestFixture.WriteSemaphoreValue(semaphoreFile, num);
 }
Beispiel #12
0
 public void FloatFunc(float num, string semaphoreFile)
 {
     TaskQueueTestFixture.WriteSemaphoreValue(semaphoreFile, num);
 }
Beispiel #13
0
 public void NullableIntFunc(int?num, string semaphoreFile)
 {
     TaskQueueTestFixture.WriteSemaphoreValue(semaphoreFile, num ?? -1);
 }
Beispiel #14
0
 public void DateTimeFunc(DateTime dateTime, string semaphoreFile)
 {
     TaskQueueTestFixture.WriteSemaphoreValue(semaphoreFile, dateTime);
 }
Beispiel #15
0
        public async Task ItExecutesScheduledTasksOnlyOnce()
        {
            const int numberOfTasks            = 1000;
            const int tasksPerTimeInterval     = 25;
            const int timeInterval             = 1000;
            const int numberOfSchedulerThreads = 4;
            TimeSpan  promotionFrequency       = TimeSpan.FromMilliseconds(100);

            ThreadPool.SetMinThreads(numberOfSchedulerThreads * 4, 200);

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

            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 <(ScheduledTask, string, string)>();

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

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

                    var scheduledTask = await taskScheduler.AddScheduledTask(
                        () => TaskQueueTestFixture.WriteSemaphoreValue(semaphoreFile, semaphoreValue),
                        TimeSpan.FromMilliseconds((i + 1) * timeInterval));

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

            _testOutputHelper.WriteLine(sw.ElapsedMilliseconds.ToString());

            var precisionAllowanceFactorMs = promotionFrequency.TotalMilliseconds + 10;

            long now;

            for (var i = 0; i < numberOfTasks / tasksPerTimeInterval; ++i)
            {
                Thread.Sleep(timeInterval);

                // EACH TASK, 3 Cases
                // CASE 1: Scheduled Time should have run, allowing for precision loss
                // CASE 2: Scheduled Time should definitely not have run
                // CASE 3: Scheduled Time is past, but within precision allowance (may have run or not)
                foreach (var task in tasks)
                {
                    now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

                    if (task.Item1.ScheduledUnixTimeMilliseconds <= (now - precisionAllowanceFactorMs))
                    {
                        File.Exists(task.Item2).Should().BeTrue();
                        File.ReadAllText(task.Item2).Should().Be(task.Item3);
                    }
                    else if (task.Item1.ScheduledUnixTimeMilliseconds > now)
                    {
                        File.Exists(task.Item2).Should().BeFalse();
                    }
                }
            }

            Thread.Sleep((int)precisionAllowanceFactorMs);

            foreach (var task in tasks)
            {
                File.Exists(task.Item2).Should().BeTrue();
                File.ReadAllText(task.Item2).Should().Be(task.Item3);
            }

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

            await Task.WhenAll(taskRunnerTasks);
        }
Beispiel #16
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);
        }