From 5a694e17579f121107e4153379c2ad1e1bbd2cf2 Mon Sep 17 00:00:00 2001 From: ExtraTNT Date: Tue, 5 Apr 2022 09:59:43 +0200 Subject: [PATCH 1/5] fix Run --- FluentScheduler/Scheduler/InternalSchedule.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/FluentScheduler/Scheduler/InternalSchedule.cs b/FluentScheduler/Scheduler/InternalSchedule.cs index 4921f932..21237cec 100644 --- a/FluentScheduler/Scheduler/InternalSchedule.cs +++ b/FluentScheduler/Scheduler/InternalSchedule.cs @@ -24,6 +24,8 @@ internal InternalSchedule(Func job, ITimeCalculator cal internal DateTime? NextRun { get; private set; } + private DateTime? LastRun { get; set; } + internal object RunningLock { get; } = new object(); internal event EventHandler JobStarted; @@ -105,7 +107,13 @@ private async Task Run(CancellationToken token) return; // calculating delay - var delay = NextRun.Value - Calculator.Now(); + // using a LastRun variable instead of now, to not get inconsistent time + TimeSpan delay; + if (LastRun.HasValue) + // every modern cpu shouldn't have a problem with running the code in under 100ms + delay = NextRun.Value - LastRun.Value - TimeSpan.FromSeconds(0.9); + else + delay = NextRun.Value - Calculator.Now(); // delaying until it's time to run or a cancellation was requested await Task.Delay(delay < TimeSpan.Zero ? TimeSpan.Zero : delay, token).ContinueWith(_ => {}); @@ -116,6 +124,7 @@ private async Task Run(CancellationToken token) // used on both JobStarted and JobEnded events var startTime = Calculator.Now(); + LastRun = startTime; // calculating the next run // used on both JobEnded event and for the next run of this method From 4d54e247d04afdfc072a094e8386a89806006577 Mon Sep 17 00:00:00 2001 From: ExtraTNT <56388556+ExtraTNT@users.noreply.github.com> Date: Tue, 5 Apr 2022 10:24:38 +0200 Subject: [PATCH 2/5] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ebbf16d..1739f702 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ # FluentScheduler -**Important note**: This branch refers to the upcoming version of the library, that's still unstable. For the current version please head to the [master branch]. +**Important note**: This fork is just a fix which counters the fact, that we do not have infinitely fast cpus (yet) Automated job scheduler with fluent interface for the .NET platform. From c8b0aad112ab3a7b4bb2d9cd1745c508381ca82d Mon Sep 17 00:00:00 2001 From: ExtraTNT Date: Tue, 5 Apr 2022 16:34:29 +0200 Subject: [PATCH 3/5] make it actually work --- FluentScheduler/Scheduler/InternalSchedule.cs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/FluentScheduler/Scheduler/InternalSchedule.cs b/FluentScheduler/Scheduler/InternalSchedule.cs index 21237cec..aa0ffe90 100644 --- a/FluentScheduler/Scheduler/InternalSchedule.cs +++ b/FluentScheduler/Scheduler/InternalSchedule.cs @@ -24,8 +24,6 @@ internal InternalSchedule(Func job, ITimeCalculator cal internal DateTime? NextRun { get; private set; } - private DateTime? LastRun { get; set; } - internal object RunningLock { get; } = new object(); internal event EventHandler JobStarted; @@ -101,19 +99,13 @@ internal void Stop(bool block, int? timeout = null) private async Task Run(CancellationToken token) { - // checking if it's supposed to run + // checking if it's supposed to run // it assumes that CalculateNextRun has been called previously from somewhere else if (!NextRun.HasValue) return; // calculating delay - // using a LastRun variable instead of now, to not get inconsistent time - TimeSpan delay; - if (LastRun.HasValue) - // every modern cpu shouldn't have a problem with running the code in under 100ms - delay = NextRun.Value - LastRun.Value - TimeSpan.FromSeconds(0.9); - else - delay = NextRun.Value - Calculator.Now(); + var delay = NextRun.Value - Calculator.Now(); // delaying until it's time to run or a cancellation was requested await Task.Delay(delay < TimeSpan.Zero ? TimeSpan.Zero : delay, token).ContinueWith(_ => {}); @@ -124,7 +116,10 @@ private async Task Run(CancellationToken token) // used on both JobStarted and JobEnded events var startTime = Calculator.Now(); - LastRun = startTime; + // start time can be before NextRun, because of the nature of CPUs + // to ensure, that this does not run code twice, we can set the startTime to the "perfect" NextRun value + if (startTime < NextRun) + startTime = NextRun.Value; // calculating the next run // used on both JobEnded event and for the next run of this method @@ -155,7 +150,7 @@ private async Task Run(CancellationToken token) // recursive call // note that the NextRun was already calculated in this run - _task = Run(token); + _task = Run(token); } } } From 28ce77f6a41e13ea55080983f12922101aa1f81a Mon Sep 17 00:00:00 2001 From: ExtraTNT Date: Tue, 5 Apr 2022 16:39:32 +0200 Subject: [PATCH 4/5] didn't want to touch the readme in this branch --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1739f702..3ebbf16d 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ # FluentScheduler -**Important note**: This fork is just a fix which counters the fact, that we do not have infinitely fast cpus (yet) +**Important note**: This branch refers to the upcoming version of the library, that's still unstable. For the current version please head to the [master branch]. Automated job scheduler with fluent interface for the .NET platform. From 249e8d1f7939738e795fe031627f816f96bc9ace Mon Sep 17 00:00:00 2001 From: ExtraTNT Date: Tue, 5 Apr 2022 16:41:09 +0200 Subject: [PATCH 5/5] remove useles whitespace --- FluentScheduler/Scheduler/InternalSchedule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FluentScheduler/Scheduler/InternalSchedule.cs b/FluentScheduler/Scheduler/InternalSchedule.cs index aa0ffe90..7bf15a0a 100644 --- a/FluentScheduler/Scheduler/InternalSchedule.cs +++ b/FluentScheduler/Scheduler/InternalSchedule.cs @@ -99,7 +99,7 @@ internal void Stop(bool block, int? timeout = null) private async Task Run(CancellationToken token) { - // checking if it's supposed to run + // checking if it's supposed to run // it assumes that CalculateNextRun has been called previously from somewhere else if (!NextRun.HasValue) return; @@ -150,7 +150,7 @@ private async Task Run(CancellationToken token) // recursive call // note that the NextRun was already calculated in this run - _task = Run(token); + _task = Run(token); } } }