diff --git a/.gitignore b/.gitignore index add57be..c6cc67a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,34 @@ -bin/ -obj/ -/packages/ -riderModule.iml -/_ReSharper.Caches/ \ No newline at end of file +# Common IntelliJ Platform excludes + +# User specific +**/.idea/**/workspace.xml +**/.idea/**/tasks.xml +**/.idea/shelf/* +**/.idea/dictionaries +**/.idea/httpRequests/ + +# Sensitive or high-churn files +**/.idea/**/dataSources/ +**/.idea/**/dataSources.ids +**/.idea/**/dataSources.xml +**/.idea/**/dataSources.local.xml +**/.idea/**/sqlDataSources.xml +**/.idea/**/dynamic.xml + +# Rider +# Rider auto-generates .iml files, and contentModel.xml +**/.idea/**/*.iml +**/.idea/**/contentModel.xml +**/.idea/**/modules.xml + +*.suo +*.user +.vs/ +[Bb]in/ +[Oo]bj/ +_UpgradeReport_Files/ +[Pp]ackages/ + +Thumbs.db +Desktop.ini +.DS_Store \ No newline at end of file diff --git a/.idea/.idea.AsyncScheduler/.idea/indexLayout.xml b/.idea/.idea.AsyncScheduler/.idea/indexLayout.xml index 27ba142..7b08163 100644 --- a/.idea/.idea.AsyncScheduler/.idea/indexLayout.xml +++ b/.idea/.idea.AsyncScheduler/.idea/indexLayout.xml @@ -1,6 +1,6 @@ - + diff --git a/.vs/AsyncScheduler/DesignTimeBuild/.dtbcache.v2 b/.vs/AsyncScheduler/DesignTimeBuild/.dtbcache.v2 deleted file mode 100644 index acc9290..0000000 Binary files a/.vs/AsyncScheduler/DesignTimeBuild/.dtbcache.v2 and /dev/null differ diff --git a/.vs/AsyncScheduler/v16/.suo b/.vs/AsyncScheduler/v16/.suo deleted file mode 100644 index aa5687a..0000000 Binary files a/.vs/AsyncScheduler/v16/.suo and /dev/null differ diff --git a/.vs/AsyncScheduler/v16/TestStore/0/003.testlog b/.vs/AsyncScheduler/v16/TestStore/0/003.testlog deleted file mode 100644 index 9597043..0000000 Binary files a/.vs/AsyncScheduler/v16/TestStore/0/003.testlog and /dev/null differ diff --git a/.vs/AsyncScheduler/v16/TestStore/0/testlog.manifest b/.vs/AsyncScheduler/v16/TestStore/0/testlog.manifest deleted file mode 100644 index 12ea347..0000000 Binary files a/.vs/AsyncScheduler/v16/TestStore/0/testlog.manifest and /dev/null differ diff --git a/.vs/DotNetAsyncScheduler/v16/.suo b/.vs/DotNetAsyncScheduler/v16/.suo deleted file mode 100644 index ac395e4..0000000 Binary files a/.vs/DotNetAsyncScheduler/v16/.suo and /dev/null differ diff --git a/.vs/DotNetAsyncScheduler/v16/TestStore/0/000.testlog b/.vs/DotNetAsyncScheduler/v16/TestStore/0/000.testlog deleted file mode 100644 index 0fdfab8..0000000 Binary files a/.vs/DotNetAsyncScheduler/v16/TestStore/0/000.testlog and /dev/null differ diff --git a/.vs/DotNetAsyncScheduler/v16/TestStore/0/testlog.manifest b/.vs/DotNetAsyncScheduler/v16/TestStore/0/testlog.manifest deleted file mode 100644 index e92ede2..0000000 Binary files a/.vs/DotNetAsyncScheduler/v16/TestStore/0/testlog.manifest and /dev/null differ diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite deleted file mode 100644 index bc90b99..0000000 Binary files a/.vs/slnx.sqlite and /dev/null differ diff --git a/AsyncScheduler.sln.DotSettings b/AsyncScheduler.sln.DotSettings index c843b27..e692fa9 100644 --- a/AsyncScheduler.sln.DotSettings +++ b/AsyncScheduler.sln.DotSettings @@ -1,2 +1,7 @@  - False \ No newline at end of file + False + True + True + True + True + True \ No newline at end of file diff --git a/AsyncScheduler.sln.DotSettings.user b/AsyncScheduler.sln.DotSettings.user deleted file mode 100644 index 5abfc11..0000000 --- a/AsyncScheduler.sln.DotSettings.user +++ /dev/null @@ -1,7 +0,0 @@ - - <SessionState ContinuousTestingMode="0" Name="UnitTest1" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> - <Project Location="E:\Projects\DotNetAsyncScheduler\AsyncSchedulerTest" Presentation="&lt;AsyncSchedulerTest&gt;" /> -</SessionState> - <SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from &lt;AsyncSchedulerTest&gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> - <Project Location="E:\Projects\DotNetAsyncScheduler\AsyncSchedulerTest" Presentation="&lt;AsyncSchedulerTest&gt;" /> -</SessionState> \ No newline at end of file diff --git a/AsyncScheduler/AsyncScheduler.csproj b/AsyncScheduler/AsyncScheduler.csproj index bc63034..e81581e 100644 --- a/AsyncScheduler/AsyncScheduler.csproj +++ b/AsyncScheduler/AsyncScheduler.csproj @@ -16,7 +16,9 @@ true false - 0.0.0 + 0.0.0 + enable + 9 diff --git a/AsyncScheduler/History/IJobHistory.cs b/AsyncScheduler/History/IJobHistory.cs index 2d5dd5d..d2a8b92 100644 --- a/AsyncScheduler/History/IJobHistory.cs +++ b/AsyncScheduler/History/IJobHistory.cs @@ -1,6 +1,4 @@ -using JetBrains.Annotations; - -namespace AsyncScheduler.History +namespace AsyncScheduler.History { /// /// Interface for accessing the history and results of finished jobs. @@ -18,15 +16,13 @@ public interface IJobHistory /// /// key of the job /// null, if no finished execution, yet - [CanBeNull] - IJobHistoryEntry GetLastJobResult(string jobKey); + IJobHistoryEntry? GetLastJobResult(string jobKey); /// /// Retrieve last result of a successful job execution. /// /// key of the job /// null, if no successful execution, yet - [CanBeNull] - IJobHistoryEntry GetLastSuccessfulJobResult(string jobKey); + IJobHistoryEntry? GetLastSuccessfulJobResult(string jobKey); } } \ No newline at end of file diff --git a/AsyncScheduler/History/IJobHistoryEntry.cs b/AsyncScheduler/History/IJobHistoryEntry.cs index 08a5ddb..a2642b8 100644 --- a/AsyncScheduler/History/IJobHistoryEntry.cs +++ b/AsyncScheduler/History/IJobHistoryEntry.cs @@ -10,7 +10,7 @@ public interface IJobHistoryEntry /// /// Execution time /// - DateTime ExecutionTime { get; } + DateTimeOffset ExecutionTime { get; } /// /// Key of the job diff --git a/AsyncScheduler/History/JobHistory.cs b/AsyncScheduler/History/JobHistory.cs index a82a2ca..24c860e 100644 --- a/AsyncScheduler/History/JobHistory.cs +++ b/AsyncScheduler/History/JobHistory.cs @@ -1,5 +1,4 @@ using System.Collections.Concurrent; -using System.Collections.Generic; namespace AsyncScheduler.History { @@ -8,26 +7,24 @@ namespace AsyncScheduler.History /// public class JobHistory : IJobHistory { - private readonly List _jobHistory = new List(); + // private readonly List _jobHistory = new(); /// /// Last execution for each job /// /// Allows efficient access for scheduling - private readonly ConcurrentDictionary _lastExecutions = - new ConcurrentDictionary(); + private readonly ConcurrentDictionary _lastExecutions = new(); /// /// Last successful execution for each job /// /// Allows efficient access for scheduling - private readonly ConcurrentDictionary _lastSuccessfulExecutions = - new ConcurrentDictionary(); + private readonly ConcurrentDictionary _lastSuccessfulExecutions = new(); /// public void Add(IJobHistoryEntry historyEntry) { - _jobHistory.Add(historyEntry); + // _jobHistory.Add(historyEntry); _lastExecutions[historyEntry.JobKey] = historyEntry; if (historyEntry.JobResult == JobResult.Success) { @@ -36,14 +33,14 @@ public void Add(IJobHistoryEntry historyEntry) } /// - public IJobHistoryEntry GetLastJobResult(string jobKey) + public IJobHistoryEntry? GetLastJobResult(string jobKey) { _lastExecutions.TryGetValue(jobKey, out var entry); return entry; } /// - public IJobHistoryEntry GetLastSuccessfulJobResult(string jobKey) + public IJobHistoryEntry? GetLastSuccessfulJobResult(string jobKey) { _lastSuccessfulExecutions.TryGetValue(jobKey, out var entry); return entry; diff --git a/AsyncScheduler/History/JobHistoryEntry.cs b/AsyncScheduler/History/JobHistoryEntry.cs index d50eff7..d82f6df 100644 --- a/AsyncScheduler/History/JobHistoryEntry.cs +++ b/AsyncScheduler/History/JobHistoryEntry.cs @@ -1,13 +1,12 @@ using System; -using JetBrains.Annotations; namespace AsyncScheduler.History { /// public class JobHistoryEntry : IJobHistoryEntry { - public JobHistoryEntry(DateTime executionTime, [NotNull] string jobKey, - JobResult jobResult, object result = null) + public JobHistoryEntry(DateTimeOffset executionTime, string jobKey, + JobResult jobResult, object? result = null) { ExecutionTime = executionTime; JobKey = jobKey ?? throw new ArgumentNullException(nameof(jobKey)); @@ -16,20 +15,18 @@ public JobHistoryEntry(DateTime executionTime, [NotNull] string jobKey, } /// - public DateTime ExecutionTime { get; } + public DateTimeOffset ExecutionTime { get; } /// - [NotNull] public string JobKey { get; } /// - public string ResultString => Result?.ToString(); + public string ResultString => Result?.ToString() ?? "null"; /// /// Result object returned by task. (Might be used later.) /// - [CanBeNull] - public object Result { get; } + public object? Result { get; } /// public JobResult JobResult { get; } diff --git a/AsyncScheduler/ISchedulerClock.cs b/AsyncScheduler/ISchedulerClock.cs index 1338a80..35195bc 100644 --- a/AsyncScheduler/ISchedulerClock.cs +++ b/AsyncScheduler/ISchedulerClock.cs @@ -7,7 +7,10 @@ namespace AsyncScheduler /// public interface ISchedulerClock { - DateTime GetNow(); + /// + /// Returns now + /// + DateTimeOffset GetNow(); } /// @@ -15,9 +18,9 @@ public interface ISchedulerClock /// internal class UtcSchedulerClock : ISchedulerClock { - public DateTime GetNow() + public DateTimeOffset GetNow() { - return DateTime.UtcNow; + return DateTimeOffset.Now; } } } \ No newline at end of file diff --git a/AsyncScheduler/JobManager.cs b/AsyncScheduler/JobManager.cs index 94f60d9..0551c16 100644 --- a/AsyncScheduler/JobManager.cs +++ b/AsyncScheduler/JobManager.cs @@ -2,7 +2,6 @@ using System.Collections.ObjectModel; using AsyncScheduler.JobStorage; using AsyncScheduler.Schedules; -using JetBrains.Annotations; using Microsoft.Extensions.Logging; namespace AsyncScheduler @@ -30,13 +29,13 @@ public JobManager(IServiceProvider serviceProvider, ILogger logger, /// /// Read access Jobs /// - public ReadOnlyDictionary Jobs => new ReadOnlyDictionary(_jobStorage.Jobs); + public ReadOnlyDictionary Jobs => new(_jobStorage.Jobs); /// /// Read access Schedules /// public ReadOnlyDictionary Schedules => - new ReadOnlyDictionary(_jobStorage.Schedules); + new(_jobStorage.Schedules); /// /// Adds a job. @@ -55,7 +54,7 @@ public void AddJob() where TJob : IJob where TSchedule : ISched /// /// schedule /// Job Type - public void AddJob([NotNull] ISchedule schedule) where TJob : IJob + public void AddJob(ISchedule schedule) where TJob : IJob { AddJob(new InstanceScheduleProvider(schedule)); } @@ -65,7 +64,7 @@ public void AddJob([NotNull] ISchedule schedule) where TJob : IJob /// /// provider/factory for schedule /// job type - public void AddJob([NotNull] IScheduleProvider scheduleProvider) where TJob : IJob + public void AddJob(IScheduleProvider scheduleProvider) where TJob : IJob { AddOrUpdateJobInternal(scheduleProvider, false, true); _logger.LogInformation("Job {jobKey} was added", typeof(TJob)); @@ -89,7 +88,7 @@ public void UpdateSchedule() where TJob : IJob where TSchedule /// /// new schedule /// Job Type - public void UpdateSchedule([NotNull] ISchedule schedule) where TJob : IJob + public void UpdateSchedule(ISchedule schedule) where TJob : IJob { UpdateSchedule(new InstanceScheduleProvider(schedule)); } @@ -99,7 +98,7 @@ public void UpdateSchedule([NotNull] ISchedule schedule) where TJob : IJob /// /// new ScheduleProvider /// Job Type - public void UpdateSchedule([NotNull] IScheduleProvider scheduleProvider) where TJob : IJob + public void UpdateSchedule(IScheduleProvider scheduleProvider) where TJob : IJob { AddOrUpdateJobInternal(scheduleProvider, true, false); _logger.LogInformation("Schedule for job {jobKey} was updated", typeof(TJob)); @@ -110,7 +109,7 @@ public void UpdateSchedule([NotNull] IScheduleProvider scheduleProvider) w /// /// ScheduleProvider /// Job Type - public void AddOrUpdate([NotNull] IScheduleProvider scheduleProvider) where TJob : IJob + public void AddOrUpdate(IScheduleProvider scheduleProvider) where TJob : IJob { AddOrUpdateJobInternal(scheduleProvider, true, true); } diff --git a/AsyncScheduler/JobStorage/InMemoryStorage.cs b/AsyncScheduler/JobStorage/InMemoryStorage.cs index a97fa77..f83ce2f 100644 --- a/AsyncScheduler/JobStorage/InMemoryStorage.cs +++ b/AsyncScheduler/JobStorage/InMemoryStorage.cs @@ -5,24 +5,30 @@ namespace AsyncScheduler.JobStorage { + /// + /// Default storage for holding the Jobs, Schedules etc. + /// It just holds the information in memory. + /// public class InMemoryStorage : IJobStorage { - private readonly ConcurrentDictionary _jobs = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _jobs = new(); - private readonly ConcurrentDictionary _schedules = - new ConcurrentDictionary(); + private readonly ConcurrentDictionary _schedules = new(); + /// public IDictionary Jobs => _jobs; + /// public IDictionary Schedules => _schedules; + /// public void AddOrUpdateJobInternal(IScheduleProvider scheduleProvider, bool update = false, bool add = true) where TJob : IJob { if (scheduleProvider == null) throw new ArgumentNullException(nameof(scheduleProvider)); var jobType = typeof(TJob); - var jobKey = jobType.FullName ?? throw new NullReferenceException("jobKey"); + string jobKey = jobType.FullName ?? throw new NullReferenceException("jobKey"); if (!add && !_jobs.ContainsKey(jobKey)) { throw new Exception($"No job {jobKey} found for updating"); @@ -37,9 +43,10 @@ public void AddOrUpdateJobInternal(IScheduleProvider scheduleProvider, boo _schedules[jobKey] = scheduleProvider; } + /// public bool Remove(string jobKey) { - var removed = _jobs.TryRemove(jobKey, out _); + bool removed = _jobs.TryRemove(jobKey, out _); if (!removed) { return false; diff --git a/AsyncScheduler/QuickStart/QuickStartRequest.cs b/AsyncScheduler/QuickStart/QuickStartRequest.cs index 308f07a..5ab1215 100644 --- a/AsyncScheduler/QuickStart/QuickStartRequest.cs +++ b/AsyncScheduler/QuickStart/QuickStartRequest.cs @@ -3,6 +3,10 @@ namespace AsyncScheduler.QuickStart { + /// + /// Quick start allows jobs to be added (e.g. via UI), which are triggered in the next run (when no restrictions apply). + /// A request can be cancelled by the user via cancellationToken. + /// internal class QuickStartRequest { private readonly CancellationToken _cancellationToken; @@ -11,11 +15,11 @@ internal class QuickStartRequest /// Requested job /// /// returns null, if request was cancelled - public string JobKey => _cancellationToken.IsCancellationRequested ? null : _jobKey; + public string? JobKey => _cancellationToken.IsCancellationRequested ? null : _jobKey; private readonly string _jobKey; - private readonly TaskCompletionSource _taskCompletionSource = new TaskCompletionSource(); + private readonly TaskCompletionSource _taskCompletionSource = new(); public QuickStartRequest(string jobKey, CancellationToken cancellationToken) { @@ -34,9 +38,7 @@ public QuickStartRequest(string jobKey, CancellationToken cancellationToken) /// true, when started; false, when not started (e.g. restrictions) public void MarkExecution(QuickStartResult success) { - // _executionResult = success; _taskCompletionSource.SetResult(success); - // _semaphoreResultAvailable.Release(); } } } \ No newline at end of file diff --git a/AsyncScheduler/QuickStartResult.cs b/AsyncScheduler/QuickStartResult.cs index c1a3786..62aded9 100644 --- a/AsyncScheduler/QuickStartResult.cs +++ b/AsyncScheduler/QuickStartResult.cs @@ -5,6 +5,9 @@ /// public enum QuickStartResult { + /// + /// Default value. Unused. + /// Unknown = 0, /// diff --git a/AsyncScheduler/Restrictions/MutexRestriction.cs b/AsyncScheduler/Restrictions/MutexRestriction.cs index b0bc83b..0679336 100644 --- a/AsyncScheduler/Restrictions/MutexRestriction.cs +++ b/AsyncScheduler/Restrictions/MutexRestriction.cs @@ -29,7 +29,7 @@ public bool RestrictStart(string jobToStart, IEnumerable runningJobs) return false; } - var isJobFromGroupAlreadyRunning = runningJobs.Any(j => _exclusiveJobGroup.Contains(j)); + bool isJobFromGroupAlreadyRunning = runningJobs.Any(j => _exclusiveJobGroup.Contains(j)); return isJobFromGroupAlreadyRunning; } } diff --git a/AsyncScheduler/Scheduler.cs b/AsyncScheduler/Scheduler.cs index 7da30fb..6fa5e3e 100644 --- a/AsyncScheduler/Scheduler.cs +++ b/AsyncScheduler/Scheduler.cs @@ -23,12 +23,12 @@ namespace AsyncScheduler /// When jobs should be executed, they are ordered by their execution policy, then each is checked for restrictions and started. public class Scheduler { - private readonly ConcurrentDictionary _runningJobs = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _runningJobs = new(); private readonly IServiceProvider _serviceProvider; private readonly ILogger _logger; private readonly ISchedulerClock _clock; - private readonly List _jobRestrictions = new List(); + private readonly List _jobRestrictions = new(); /// /// Determines the delay between each run, where the schedules are checked. @@ -66,7 +66,7 @@ public Scheduler(IServiceProvider serviceProvider, ILogger logger, IS /// Jobs added here are executed in the next loop (when no restrictions apply). /// Job is removed from queue, when executed or restrictions apply during execution. /// - private ConcurrentQueue QuickStartQueue { get; } = new ConcurrentQueue(); + private ConcurrentQueue QuickStartQueue { get; } = new(); /// /// Jobs added here are executed in the next loop (when no restrictions apply). @@ -141,7 +141,7 @@ public async Task Start(CancellationToken cancellationToken) _logger.LogDebug(e, "Execution loop was cancelled by CancellationToken"); } - Task finishUpTask = null; + Task? finishUpTask = null; try { _logger.LogInformation("Scheduler stopped. Waiting for running jobs to finish: {jobCount}", @@ -179,7 +179,7 @@ private async Task HandleShutdownFinished(string jobKey, Task shutdownTa { try { - var result = await shutdownTask; + string result = await shutdownTask; _logger.LogInformation("Shutdown job for {jobKey} finished with result: {result}", jobKey, result); } catch (Exception e) @@ -216,7 +216,7 @@ private void ExecuteQuickStarts(CancellationToken cancellationToken) { while (QuickStartQueue.TryDequeue(out var quickStartRequest)) { - var resultJobKey = quickStartRequest.JobKey; + string? resultJobKey = quickStartRequest.JobKey; if (resultJobKey == null) { continue; @@ -229,7 +229,7 @@ private void ExecuteQuickStarts(CancellationToken cancellationToken) } var job = JobManager.Jobs.Single(j => j.Key == resultJobKey); - var success = CheckRestrictionsAndStartJob(cancellationToken, job); + bool success = CheckRestrictionsAndStartJob(cancellationToken, job); _logger.LogInformation("Quick start of {jobKey} was successful: {started}", job.Key, success); quickStartRequest.MarkExecution(success ? QuickStartResult.Started : QuickStartResult.Restricted); cancellationToken.ThrowIfCancellationRequested(); @@ -261,7 +261,7 @@ private int GetJobExecutionPriority(string jobKey) var lastSuccessfulExecution = JobHistory.GetLastSuccessfulJobResult(jobKey); try { - var executionPriority = schedule.GetExecutionPriority(jobKey, jobHistoryEntry, lastSuccessfulExecution, _clock.GetNow()); + int executionPriority = schedule.GetExecutionPriority(jobKey, jobHistoryEntry, lastSuccessfulExecution, _clock.GetNow()); _logger.LogTrace("Execution priority from scheduler for job {jobKey} is {priority}", jobKey, executionPriority); return executionPriority; } @@ -272,7 +272,7 @@ private int GetJobExecutionPriority(string jobKey) } } - private ISchedule GetSchedule(string jobKey) + private ISchedule? GetSchedule(string jobKey) { JobManager.Schedules.TryGetValue(jobKey, out var scheduleProvider); if (scheduleProvider == null) @@ -309,7 +309,7 @@ private bool IsStartRestricted(string jobKey) var runningJobs = _runningJobs.Where(j => j.Value != null).Select(j => j.Key); return _jobRestrictions.Select(restriction => { - var restrictStart = restriction.RestrictStart(jobKey, runningJobs); + bool restrictStart = restriction.RestrictStart(jobKey, runningJobs); if (restrictStart) { _logger.LogTrace("JobStartRestriction for {jobKey} detected by {restriction}", jobKey, restriction.GetType()); @@ -350,8 +350,7 @@ private void StartJob(CancellationToken cancellationToken, KeyValuePair job) + private IJob? CreateJobInstance(KeyValuePair job) { try { @@ -372,7 +371,7 @@ private async void ResolveTaskEnd(string jobKey, Task task) { try { - var result = await task; + object result = await task; _logger.LogInformation("Job {jobKey} finished: {result}", jobKey, result); JobHistory.Add(new JobHistoryEntry(_clock.GetNow(), jobKey, JobResult.Success, result)); } diff --git a/AsyncScheduler/Schedules/ISchedule.cs b/AsyncScheduler/Schedules/ISchedule.cs index 6331615..f98119d 100644 --- a/AsyncScheduler/Schedules/ISchedule.cs +++ b/AsyncScheduler/Schedules/ISchedule.cs @@ -16,7 +16,6 @@ public interface ISchedule /// /// Priority only plays a role, if restrictions are applied. /// 0 = don't execute - int GetExecutionPriority(string jobKey, IJobHistoryEntry lastExecution, - IJobHistoryEntry lastSuccessfulExecution, DateTime now); + int GetExecutionPriority(string jobKey, IJobHistoryEntry? lastExecution, IJobHistoryEntry? lastSuccessfulExecution, DateTimeOffset now); } } \ No newline at end of file diff --git a/AsyncScheduler/Schedules/IScheduleProvider.cs b/AsyncScheduler/Schedules/IScheduleProvider.cs index b18160b..72d2d59 100644 --- a/AsyncScheduler/Schedules/IScheduleProvider.cs +++ b/AsyncScheduler/Schedules/IScheduleProvider.cs @@ -1,6 +1,4 @@ -using JetBrains.Annotations; - -namespace AsyncScheduler.Schedules +namespace AsyncScheduler.Schedules { /// /// Common interface to provide a schedule for a job. @@ -13,7 +11,6 @@ public interface IScheduleProvider /// Provides or instantiates the schedule. /// /// schedule - [CanBeNull] - ISchedule GetSchedule(); + ISchedule? GetSchedule(); } } \ No newline at end of file diff --git a/AsyncScheduler/Schedules/InstanceScheduleProvider.cs b/AsyncScheduler/Schedules/InstanceScheduleProvider.cs index 8a1a8f6..c5467a0 100644 --- a/AsyncScheduler/Schedules/InstanceScheduleProvider.cs +++ b/AsyncScheduler/Schedules/InstanceScheduleProvider.cs @@ -1,6 +1,4 @@ -using System; - -namespace AsyncScheduler.Schedules +namespace AsyncScheduler.Schedules { /// /// A ScheduleProvider for a given schedule instance diff --git a/AsyncScheduler/Schedules/IntervalSchedule.cs b/AsyncScheduler/Schedules/IntervalSchedule.cs index 6a20abe..637510d 100644 --- a/AsyncScheduler/Schedules/IntervalSchedule.cs +++ b/AsyncScheduler/Schedules/IntervalSchedule.cs @@ -6,7 +6,7 @@ namespace AsyncScheduler.Schedules /// /// Trigger the job immediately and then after the given timespan expired. /// - public class IntervalSchedule : ISchedule, IScheduleWithPrio + public class IntervalSchedule : IScheduleWithPrio { /// /// Create interval schedule with the given interval @@ -23,9 +23,9 @@ public IntervalSchedule(TimeSpan interval) public TimeSpan Interval { get; set; } /// - public int GetExecutionPriority(string jobKey, IJobHistoryEntry lastExecution, - IJobHistoryEntry lastSuccessfulExecution, - DateTime now) + public int GetExecutionPriority(string jobKey, IJobHistoryEntry? lastExecution, + IJobHistoryEntry? lastSuccessfulExecution, + DateTimeOffset now) { if (lastExecution == null) { @@ -35,7 +35,7 @@ public int GetExecutionPriority(string jobKey, IJobHistoryEntry lastExecution, if (lastExecution.ExecutionTime + Interval < now) { var delay = now - (lastExecution.ExecutionTime + Interval); - var delayTotalMinutes = (int) delay.TotalMinutes * Priority; + int delayTotalMinutes = (int) delay.TotalMinutes * Priority; return Math.Max(delayTotalMinutes, Priority); } diff --git a/AsyncScheduler/Schedules/IntervalScheduleWithRetryDelay.cs b/AsyncScheduler/Schedules/IntervalScheduleWithRetryDelay.cs index fbd045c..0e17120 100644 --- a/AsyncScheduler/Schedules/IntervalScheduleWithRetryDelay.cs +++ b/AsyncScheduler/Schedules/IntervalScheduleWithRetryDelay.cs @@ -6,7 +6,7 @@ namespace AsyncScheduler.Schedules /// /// Trigger job as in but retry failed attempts after the retry delay. /// - public class IntervalScheduleWithRetryDelay : IScheduleWithPrio, ISchedule + public class IntervalScheduleWithRetryDelay : IScheduleWithPrio { private readonly IntervalSchedule _intervalSchedule; @@ -20,14 +20,14 @@ public IntervalScheduleWithRetryDelay(TimeSpan interval) } /// - public int GetExecutionPriority(string jobKey, IJobHistoryEntry lastExecution, IJobHistoryEntry lastSuccessfulExecution, DateTime now) + public int GetExecutionPriority(string jobKey, IJobHistoryEntry? lastExecution, IJobHistoryEntry? lastSuccessfulExecution, DateTimeOffset now) { - var basePriority = _intervalSchedule.GetExecutionPriority(jobKey, lastExecution, lastSuccessfulExecution, now); + int basePriority = _intervalSchedule.GetExecutionPriority(jobKey, lastExecution, lastSuccessfulExecution, now); if (basePriority > 0) { return basePriority; } - if (lastExecution.JobResult == JobResult.Failure) + if (lastExecution?.JobResult == JobResult.Failure) { // Don't retry immediately if (lastExecution.ExecutionTime + RetryDelay > now) diff --git a/AsyncScheduler/Schedules/ScheduleEndless.cs b/AsyncScheduler/Schedules/ScheduleEndless.cs index 672c472..de33984 100644 --- a/AsyncScheduler/Schedules/ScheduleEndless.cs +++ b/AsyncScheduler/Schedules/ScheduleEndless.cs @@ -6,11 +6,11 @@ namespace AsyncScheduler.Schedules /// /// Always run the task (when it is not running anymore). /// - public class ScheduleEndless : ISchedule, IScheduleWithPrio + public class ScheduleEndless : IScheduleWithPrio { /// - public int GetExecutionPriority(string jobKey, IJobHistoryEntry lastExecution, IJobHistoryEntry lastSuccessfulExecution, - DateTime now) + public int GetExecutionPriority(string jobKey, IJobHistoryEntry? lastExecution, IJobHistoryEntry? lastSuccessfulExecution, + DateTimeOffset now) { return Priority; } diff --git a/AsyncScheduler/Schedules/ScheduleNever.cs b/AsyncScheduler/Schedules/ScheduleNever.cs index c1b7217..413f731 100644 --- a/AsyncScheduler/Schedules/ScheduleNever.cs +++ b/AsyncScheduler/Schedules/ScheduleNever.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using AsyncScheduler.History; namespace AsyncScheduler.Schedules @@ -13,7 +9,7 @@ namespace AsyncScheduler.Schedules public class ScheduleNever : ISchedule { /// - public int GetExecutionPriority(string jobKey, IJobHistoryEntry lastExecution, IJobHistoryEntry lastSuccessfulExecution, DateTime now) + public int GetExecutionPriority(string jobKey, IJobHistoryEntry? lastExecution, IJobHistoryEntry? lastSuccessfulExecution, DateTimeOffset now) { return 0; } diff --git a/AsyncScheduler/Schedules/ScheduleOnce.cs b/AsyncScheduler/Schedules/ScheduleOnce.cs index b0fe100..37e7a32 100644 --- a/AsyncScheduler/Schedules/ScheduleOnce.cs +++ b/AsyncScheduler/Schedules/ScheduleOnce.cs @@ -6,11 +6,11 @@ namespace AsyncScheduler.Schedules /// /// Simple schedule to execute task once without delay. On failure no rescheduling. /// - public class ScheduleOnce : ISchedule, IScheduleWithPrio + public class ScheduleOnce : IScheduleWithPrio { /// - public int GetExecutionPriority(string jobKey, IJobHistoryEntry lastExecution, IJobHistoryEntry lastSuccessfulExecution, - DateTime now) + public int GetExecutionPriority(string jobKey, IJobHistoryEntry? lastExecution, IJobHistoryEntry? lastSuccessfulExecution, + DateTimeOffset now) { return lastExecution == null ? Priority : 0; } diff --git a/AsyncScheduler/Schedules/ScheduleOnceWithRetryDelay.cs b/AsyncScheduler/Schedules/ScheduleOnceWithRetryDelay.cs index d84b82b..ca8e7da 100644 --- a/AsyncScheduler/Schedules/ScheduleOnceWithRetryDelay.cs +++ b/AsyncScheduler/Schedules/ScheduleOnceWithRetryDelay.cs @@ -7,7 +7,7 @@ namespace AsyncScheduler.Schedules /// Schedule which executes task once without delay. /// On failed execution, execution is retried again and again with . /// - public class ScheduleOnceWithRetryDelay : ISchedule, IScheduleWithPrio + public class ScheduleOnceWithRetryDelay : IScheduleWithPrio { /// /// Delay for retry after failed execution. @@ -15,8 +15,8 @@ public class ScheduleOnceWithRetryDelay : ISchedule, IScheduleWithPrio public TimeSpan RetryDelay { get; set; } = TimeSpan.FromSeconds(30); /// - public int GetExecutionPriority(string jobKey, IJobHistoryEntry lastExecution, IJobHistoryEntry lastSuccessfulExecution, - DateTime now) + public int GetExecutionPriority(string jobKey, IJobHistoryEntry? lastExecution, IJobHistoryEntry? lastSuccessfulExecution, + DateTimeOffset now) { if (lastSuccessfulExecution == null) { //Hint: Delayed retry diff --git a/AsyncScheduler/Schedules/TimeSlotSchedule.cs b/AsyncScheduler/Schedules/TimeSlotSchedule.cs index 78a1787..0a1a923 100644 --- a/AsyncScheduler/Schedules/TimeSlotSchedule.cs +++ b/AsyncScheduler/Schedules/TimeSlotSchedule.cs @@ -8,12 +8,12 @@ namespace AsyncScheduler.Schedules /// On failure task is immediately restarted. /// A similar implementation could be done, where the StartTime is automatically fetched from Database or Filesystem. /// - public class TimeSlotSchedule : ISchedule, IScheduleWithPrio + public class TimeSlotSchedule : IScheduleWithPrio { /// /// Earliest time for the task to start. /// - public DateTime StartTime { get; set; } + public DateTimeOffset StartTime { get; set; } /// /// If task has not been successful executed in this time span, it is not triggered. @@ -22,10 +22,10 @@ public class TimeSlotSchedule : ISchedule, IScheduleWithPrio public TimeSpan SlotTime { get; set; } = TimeSpan.FromMinutes(10); /// - public int GetExecutionPriority(string jobKey, IJobHistoryEntry lastExecution, IJobHistoryEntry lastSuccessfulExecution, - DateTime now) + public int GetExecutionPriority(string jobKey, IJobHistoryEntry? lastExecution, IJobHistoryEntry? lastSuccessfulExecution, + DateTimeOffset now) { - var lastExecutionTime = lastSuccessfulExecution?.ExecutionTime ?? DateTime.MinValue; + var lastExecutionTime = lastSuccessfulExecution?.ExecutionTime ?? DateTimeOffset.MinValue; if (now > StartTime && lastExecutionTime < StartTime && now < StartTime + SlotTime) { return Priority; diff --git a/AsyncSchedulerTest/AsyncSchedulerTest.csproj b/AsyncSchedulerTest/AsyncSchedulerTest.csproj index b2792d9..009b7d2 100644 --- a/AsyncSchedulerTest/AsyncSchedulerTest.csproj +++ b/AsyncSchedulerTest/AsyncSchedulerTest.csproj @@ -3,6 +3,8 @@ false net472;netcoreapp3.1;netcoreapp2.1 + enable + 9 diff --git a/AsyncSchedulerTest/JobManagerTest.cs b/AsyncSchedulerTest/JobManagerTest.cs index c0bdeeb..2adffe4 100644 --- a/AsyncSchedulerTest/JobManagerTest.cs +++ b/AsyncSchedulerTest/JobManagerTest.cs @@ -26,10 +26,10 @@ public void AddJobViaWithScheduleInstance_JobAdded() _jobManager.Jobs.Should().HaveCount(1); _jobManager.Schedules.Should().HaveCount(1); - var jobKey = typeof(NotImplementedJob).FullName; - _jobManager.Jobs[jobKey].Should().Be(); + string? jobKey = typeof(NotImplementedJob).FullName; + _jobManager.Jobs[jobKey!].Should().Be(); // ReSharper disable once SuspiciousTypeConversion.Global - ((NotImplementedSchedule) _jobManager.Schedules[jobKey].GetSchedule())?.Marker.Should().Be("1"); + ((NotImplementedSchedule?) _jobManager.Schedules[jobKey!].GetSchedule())?.Marker.Should().Be("1"); } [Fact] @@ -39,10 +39,10 @@ public void AddJobViaGeneric_JobAdded() _jobManager.Jobs.Should().HaveCount(1); _jobManager.Schedules.Should().HaveCount(1); - var jobKey = typeof(NotImplementedJob).FullName; - _jobManager.Jobs[jobKey].Should().Be(); - var firstSchedule = (NotImplementedSchedule) _jobManager.Schedules[jobKey].GetSchedule(); - var secondSchedule = (NotImplementedSchedule) _jobManager.Schedules[jobKey].GetSchedule(); + string? jobKey = typeof(NotImplementedJob).FullName; + _jobManager.Jobs[jobKey!].Should().Be(); + var firstSchedule = (NotImplementedSchedule?) _jobManager.Schedules[jobKey!].GetSchedule(); + var secondSchedule = (NotImplementedSchedule?) _jobManager.Schedules[jobKey!].GetSchedule(); firstSchedule?.Marker.Should().Be("DI"); // Each instance is newly requested. firstSchedule.Should().NotBeSameAs(secondSchedule); @@ -55,8 +55,8 @@ public void AddJobTwice_Throws() Action add = () => _jobManager.AddJob(new NotImplementedSchedule("2")); add.Should().Throw(); - var jobKey = typeof(NotImplementedJob).FullName; - ((NotImplementedSchedule) _jobManager.Schedules[jobKey].GetSchedule())?.Marker.Should().Be("1"); + string? jobKey = typeof(NotImplementedJob).FullName; + ((NotImplementedSchedule?) _jobManager.Schedules[jobKey!].GetSchedule())?.Marker.Should().Be("1"); } [Fact] @@ -67,9 +67,9 @@ public void UpdateJobWithScheduleInstance_JobUpdated() _jobManager.Jobs.Should().HaveCount(1); _jobManager.Schedules.Should().HaveCount(1); - var jobKey = typeof(NotImplementedJob).FullName; - _jobManager.Jobs[jobKey].Should().Be(); - ((NotImplementedSchedule) _jobManager.Schedules[jobKey].GetSchedule())?.Marker.Should().Be("2"); + string? jobKey = typeof(NotImplementedJob).FullName; + _jobManager.Jobs[jobKey!].Should().Be(); + ((NotImplementedSchedule?) _jobManager.Schedules[jobKey!].GetSchedule())?.Marker.Should().Be("2"); } [Fact] diff --git a/AsyncSchedulerTest/Restrictions/ConcurrentJobRestrictionTest.cs b/AsyncSchedulerTest/Restrictions/ConcurrentJobRestrictionTest.cs index d59e5f7..51275ea 100644 --- a/AsyncSchedulerTest/Restrictions/ConcurrentJobRestrictionTest.cs +++ b/AsyncSchedulerTest/Restrictions/ConcurrentJobRestrictionTest.cs @@ -11,7 +11,7 @@ public void ShouldNotRestrictJobsWhenLimitNotReached() { var concurrentJobRestriction = new ConcurrentJobRestriction {MaximumParallelJobs = 3}; - concurrentJobRestriction.RestrictStart("job", new string[] {"1", "2"}).Should().BeFalse(); + concurrentJobRestriction.RestrictStart("job", new[] {"1", "2"}).Should().BeFalse(); } [Fact] @@ -19,7 +19,7 @@ public void ShouldRestrictJobsWhenLimitReached() { var concurrentJobRestriction = new ConcurrentJobRestriction {MaximumParallelJobs = 3}; - concurrentJobRestriction.RestrictStart("job", new string[] {"1", "2", "3"}).Should().BeTrue(); + concurrentJobRestriction.RestrictStart("job", new[] {"1", "2", "3"}).Should().BeTrue(); } [Fact] @@ -27,7 +27,7 @@ public void ShouldNotRestrictJobsInExceptionList() { var concurrentJobRestriction = new ConcurrentJobRestriction {MaximumParallelJobs = 1, ExceptionList = new[] {"job"}}; - concurrentJobRestriction.RestrictStart("job", new string[] {"1", "2"}).Should().BeFalse(); + concurrentJobRestriction.RestrictStart("job", new[] {"1", "2"}).Should().BeFalse(); } [Fact] @@ -35,7 +35,7 @@ public void ShouldNotCountOneJobInExceptionList() { var concurrentJobRestriction = new ConcurrentJobRestriction {MaximumParallelJobs = 2, ExceptionList = new[] {"job"}}; - concurrentJobRestriction.RestrictStart("1", new string[] {"job", "2"}).Should().BeFalse(); + concurrentJobRestriction.RestrictStart("1", new[] {"job", "2"}).Should().BeFalse(); } [Fact] @@ -43,7 +43,7 @@ public void ShouldNotCountAllJobsInExceptionList() { var concurrentJobRestriction = new ConcurrentJobRestriction {MaximumParallelJobs = 1, ExceptionList = new[] {"job2", "job"}}; - concurrentJobRestriction.RestrictStart("1", new string[] {"job", "job2"}).Should().BeFalse(); + concurrentJobRestriction.RestrictStart("1", new[] {"job", "job2"}).Should().BeFalse(); } } } \ No newline at end of file diff --git a/AsyncSchedulerTest/SchedulerMultipleJobsTest.cs b/AsyncSchedulerTest/SchedulerMultipleJobsTest.cs index 1372067..6cd8ff7 100644 --- a/AsyncSchedulerTest/SchedulerMultipleJobsTest.cs +++ b/AsyncSchedulerTest/SchedulerMultipleJobsTest.cs @@ -1,10 +1,8 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using AsyncScheduler; -using AsyncScheduler.History; using AsyncScheduler.JobStorage; using AsyncScheduler.Restrictions; using AsyncScheduler.Schedules; @@ -38,15 +36,16 @@ public async Task AddMoreJobs_ScheduleOnce_ExecutesAllJobs() _scheduler.JobManager.AddJob(); _scheduler.JobManager.AddJob(); await RunScheduler(TimeSpan.FromSeconds(1)); - var jobKey = typeof(SimpleJob).FullName; + string jobKey = typeof(SimpleJob).FullName!; var lastSuccessfulJobResult = _scheduler.JobHistory.GetLastSuccessfulJobResult(jobKey); lastSuccessfulJobResult.Should().NotBeNull(); - _scheduler.JobHistory.GetLastSuccessfulJobResult(typeof(NotImplementedJob).FullName).Should().BeNull(); - _scheduler.JobHistory.GetLastSuccessfulJobResult(typeof(AsyncExceptionJob).FullName).Should().BeNull(); + _scheduler.JobHistory.GetLastSuccessfulJobResult(typeof(NotImplementedJob).FullName!).Should().BeNull(); + _scheduler.JobHistory.GetLastSuccessfulJobResult(typeof(AsyncExceptionJob).FullName!).Should().BeNull(); - _scheduler.JobHistory.GetLastJobResult(typeof(NotImplementedJob).FullName).Should().NotBeNull(); - _scheduler.JobHistory.GetLastJobResult(typeof(AsyncExceptionJob).FullName).Should().NotBeNull(); + _scheduler.JobHistory.GetLastJobResult(typeof(NotImplementedJob).FullName!).Should().NotBeNull(); + _scheduler.JobHistory.GetLastJobResult(typeof(AsyncExceptionJob).FullName!).Should().NotBeNull(); + _scheduler.CurrentlyRunningJobs.Should().BeEmpty(); } [Fact] @@ -62,8 +61,8 @@ public async Task AddMoreJobs_RestrictParallelExecution_ExecutesOnlyOneJobs() await RunScheduler(TimeSpan.FromSeconds(1)); // Only one job should have been executed: - var sj = _scheduler.JobHistory.GetLastJobResult(typeof(SimpleJob).FullName); - var aej = _scheduler.JobHistory.GetLastJobResult(typeof(AsyncExceptionJob).FullName); + var sj = _scheduler.JobHistory.GetLastJobResult(typeof(SimpleJob).FullName!); + var aej = _scheduler.JobHistory.GetLastJobResult(typeof(AsyncExceptionJob).FullName!); var jobHistoryEntries = new[] {sj, aej}; jobHistoryEntries.Should().ContainSingle(e => e != null); @@ -73,10 +72,10 @@ public async Task AddMoreJobs_RestrictParallelExecution_ExecutesOnlyOneJobs() private async Task RunScheduler(TimeSpan schedulerTime) { - CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); + var cancellationTokenSource = new CancellationTokenSource(); var schedulerTask = _scheduler.Start(cancellationTokenSource.Token); // ReSharper disable MethodSupportsCancellation - await Task.Delay(schedulerTime).ContinueWith((t) => cancellationTokenSource.Cancel()); + await Task.Delay(schedulerTime).ContinueWith(_ => cancellationTokenSource.Cancel()); var schedulerFinishTimeout = TimeSpan.FromSeconds(1); await Task.WhenAny(schedulerTask, Task.Delay(schedulerFinishTimeout)); // ReSharper restore MethodSupportsCancellation diff --git a/AsyncSchedulerTest/SchedulerOneJobTest.cs b/AsyncSchedulerTest/SchedulerOneJobTest.cs index 1979a85..a245b35 100644 --- a/AsyncSchedulerTest/SchedulerOneJobTest.cs +++ b/AsyncSchedulerTest/SchedulerOneJobTest.cs @@ -34,7 +34,7 @@ public async Task AddOneJob_ScheduleOnce_ExecutesJob() { _scheduler.JobManager.AddJob(); await RunScheduler(TimeSpan.FromSeconds(0.5)); - var jobKey = typeof(SimpleJob).FullName; + string jobKey = typeof(SimpleJob).FullName!; var lastSuccessfulJobResult = _scheduler.JobHistory.GetLastSuccessfulJobResult(jobKey); lastSuccessfulJobResult.Should().NotBeNull(); _scheduler.JobHistory.GetLastJobResult(jobKey).Should() @@ -50,7 +50,7 @@ public async Task AddOneJob_ScheduleThrowsException_ShouldBeHandled() { _scheduler.JobManager.AddJob(); await RunScheduler(TimeSpan.FromSeconds(0.5)); - var jobKey = typeof(SimpleJob).FullName; + string jobKey = typeof(SimpleJob).FullName!; var lastSuccessfulJobResult = _scheduler.JobHistory.GetLastSuccessfulJobResult(jobKey); lastSuccessfulJobResult.Should().BeNull(); _scheduler.JobHistory.GetLastJobResult(jobKey).Should().BeNull(); @@ -65,7 +65,7 @@ public async Task AddOneJob_ScheduleNever_QuickStartJob_ExecutesJobViaQuickStart var quickStartTask = _scheduler.QuickStart(); await runSchedulerTask; - var jobKey = typeof(SimpleJob).FullName; + string jobKey = typeof(SimpleJob).FullName!; var lastSuccessfulJobResult = _scheduler.JobHistory.GetLastSuccessfulJobResult(jobKey); lastSuccessfulJobResult.Should().NotBeNull(); _scheduler.JobHistory.GetLastJobResult(jobKey).Should() @@ -96,7 +96,7 @@ public async Task AddStartFailingJob_ScheduleOnce_ExecutesJobAndMarksResult() { _scheduler.JobManager.AddJob(); await RunScheduler(TimeSpan.FromSeconds(0.5)); - var jobKey = typeof(NotImplementedJob).FullName; + string jobKey = typeof(NotImplementedJob).FullName!; _scheduler.JobHistory.GetLastSuccessfulJobResult(jobKey).Should().BeNull(); var lastResult = _scheduler.JobHistory.GetLastJobResult(jobKey); lastResult.Should().NotBeNull(); @@ -112,7 +112,7 @@ public async Task AddAsyncFailingJob_ScheduleOnce_ExecutesJobAndMarksResult() { _scheduler.JobManager.AddJob(); await RunScheduler(TimeSpan.FromSeconds(0.5)); - var jobKey = typeof(AsyncExceptionJob).FullName; + string jobKey = typeof(AsyncExceptionJob).FullName!; _scheduler.JobHistory.GetLastSuccessfulJobResult(jobKey).Should().BeNull(); var lastResult = _scheduler.JobHistory.GetLastJobResult(jobKey); lastResult.Should().NotBeNull(); @@ -126,7 +126,7 @@ public async Task AddAsyncFailingJob_ScheduleOnce_ExecutesJobAndMarksResult() [Fact] public async Task AddOneJob_ScheduleEndless_ExecutesJobSeveralTimes() { - var executionCountBefore = _simpleJobInstance.ExecutionCount; + int executionCountBefore = _simpleJobInstance.ExecutionCount; // Hint: We reduce the delay for each run _scheduler.LoopDelay = TimeSpan.FromSeconds(0.1); _scheduler.JobManager.AddJob(); @@ -134,7 +134,7 @@ public async Task AddOneJob_ScheduleEndless_ExecutesJobSeveralTimes() // Act await RunScheduler(TimeSpan.FromSeconds(2)); - var jobKey = typeof(SimpleJob).FullName; + string jobKey = typeof(SimpleJob).FullName!; var lastSuccessfulJobResult = _scheduler.JobHistory.GetLastSuccessfulJobResult(jobKey); lastSuccessfulJobResult.Should().NotBeNull(); _scheduler.JobHistory.GetLastJobResult(jobKey).Should() @@ -150,7 +150,7 @@ public async Task AddOneJob_ScheduleEndless_ExecutesJobSeveralTimes() [Fact] public async Task AddOneJob_ScheduleEndless_RemoveJobInBetween_ExecutesJobSeveralTimes() { - var executionCountBefore = _simpleJobInstance.ExecutionCount; + int executionCountBefore = _simpleJobInstance.ExecutionCount; // Hint: We reduce the delay for each run _scheduler.LoopDelay = TimeSpan.FromSeconds(0.1); _scheduler.JobManager.AddJob(); @@ -162,7 +162,7 @@ public async Task AddOneJob_ScheduleEndless_RemoveJobInBetween_ExecutesJobSevera _scheduler.JobManager.RemoveJob(); await schedulerTask; - var jobKey = typeof(SimpleJob).FullName; + string jobKey = typeof(SimpleJob).FullName!; var lastSuccessfulJobResult = _scheduler.JobHistory.GetLastSuccessfulJobResult(jobKey); lastSuccessfulJobResult.Should().NotBeNull(); _scheduler.JobHistory.GetLastJobResult(jobKey).Should() @@ -178,7 +178,7 @@ public async Task AddOneJob_ScheduleEndless_RemoveJobInBetween_ExecutesJobSevera [Fact] public async Task AddOneJob_ScheduleOnce_UpdateScheduleTo_ScheduleEndless_ExecutesJobSeveralTimes() { - var executionCountBefore = _simpleJobInstance.ExecutionCount; + int executionCountBefore = _simpleJobInstance.ExecutionCount; // Hint: We reduce the delay for each run _scheduler.LoopDelay = TimeSpan.FromSeconds(0.1); _scheduler.JobManager.AddJob(); @@ -192,7 +192,7 @@ public async Task AddOneJob_ScheduleOnce_UpdateScheduleTo_ScheduleEndless_Execut _scheduler.JobManager.UpdateSchedule(); await schedulerTask; - var jobKey = typeof(SimpleJob).FullName; + string jobKey = typeof(SimpleJob).FullName!; var lastSuccessfulJobResult = _scheduler.JobHistory.GetLastSuccessfulJobResult(jobKey); lastSuccessfulJobResult.Should().NotBeNull(); _scheduler.JobHistory.GetLastJobResult(jobKey).Should() @@ -207,10 +207,10 @@ public async Task AddOneJob_ScheduleOnce_UpdateScheduleTo_ScheduleEndless_Execut private async Task RunScheduler(TimeSpan schedulerTime) { - CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); + var cancellationTokenSource = new CancellationTokenSource(); var schedulerTask = _scheduler.Start(cancellationTokenSource.Token); // ReSharper disable MethodSupportsCancellation - await Task.Delay(schedulerTime).ContinueWith((t) => cancellationTokenSource.Cancel()); + await Task.Delay(schedulerTime).ContinueWith(_ => cancellationTokenSource.Cancel()); var schedulerFinishTimeout = TimeSpan.FromSeconds(1); await Task.WhenAny(schedulerTask, Task.Delay(schedulerFinishTimeout)); cancellationTokenSource.Cancel(); diff --git a/AsyncSchedulerTest/Schedules/IntervalScheduleTest.cs b/AsyncSchedulerTest/Schedules/IntervalScheduleTest.cs index 8be7653..5ea7c2d 100644 --- a/AsyncSchedulerTest/Schedules/IntervalScheduleTest.cs +++ b/AsyncSchedulerTest/Schedules/IntervalScheduleTest.cs @@ -8,7 +8,7 @@ namespace AsyncSchedulerTest.Schedules { public class IntervalScheduleTest { - private readonly IntervalSchedule _schedule = new IntervalSchedule(TimeSpan.FromMinutes(2)); + private readonly IntervalSchedule _schedule = new(TimeSpan.FromMinutes(2)); private readonly string _jobKey = "keyNotUsed"; diff --git a/AsyncSchedulerTest/Schedules/IntervalScheduleWithRetryDelayTest.cs b/AsyncSchedulerTest/Schedules/IntervalScheduleWithRetryDelayTest.cs index ac1b2bf..8fec75a 100644 --- a/AsyncSchedulerTest/Schedules/IntervalScheduleWithRetryDelayTest.cs +++ b/AsyncSchedulerTest/Schedules/IntervalScheduleWithRetryDelayTest.cs @@ -8,7 +8,7 @@ namespace AsyncSchedulerTest.Schedules { public class IntervalScheduleWithRetryDelayTest { - private readonly IntervalScheduleWithRetryDelay _schedule = new IntervalScheduleWithRetryDelay(TimeSpan.FromMinutes(2)); + private readonly IntervalScheduleWithRetryDelay _schedule = new(TimeSpan.FromMinutes(2)); private readonly string _jobKey = "keyNotUsed"; diff --git a/AsyncSchedulerTest/Schedules/ScheduleOnceWithRetryDelayTest.cs b/AsyncSchedulerTest/Schedules/ScheduleOnceWithRetryDelayTest.cs index 0f582ae..aae41c7 100644 --- a/AsyncSchedulerTest/Schedules/ScheduleOnceWithRetryDelayTest.cs +++ b/AsyncSchedulerTest/Schedules/ScheduleOnceWithRetryDelayTest.cs @@ -8,7 +8,7 @@ namespace AsyncSchedulerTest.Schedules { public class ScheduleOnceWithRetryDelayTest { - private readonly ScheduleOnceWithRetryDelay _schedule = new ScheduleOnceWithRetryDelay(); + private readonly ScheduleOnceWithRetryDelay _schedule = new(); private readonly string _jobKey = "keyNotUsed"; diff --git a/AsyncSchedulerTest/Schedules/TimeSlotScheduleTest.cs b/AsyncSchedulerTest/Schedules/TimeSlotScheduleTest.cs index 13551db..d39d1bc 100644 --- a/AsyncSchedulerTest/Schedules/TimeSlotScheduleTest.cs +++ b/AsyncSchedulerTest/Schedules/TimeSlotScheduleTest.cs @@ -8,13 +8,13 @@ namespace AsyncSchedulerTest.Schedules { public class TimeSlotScheduleTest { - private readonly TimeSlotSchedule _timeSlotSchedule = new TimeSlotSchedule + private readonly TimeSlotSchedule _timeSlotSchedule = new() { StartTime = StartTime, SlotTime = TimeSpan.FromMinutes(10) }; - private static readonly DateTime StartTime = new DateTime(2020, 8, 2, 20, 00, 00); + private static readonly DateTime StartTime = new(2020, 8, 2, 20, 00, 00); private readonly string _jobKey = "keyNotUsed"; [Fact] diff --git a/AsyncSchedulerTest/ShutdownJobTest.cs b/AsyncSchedulerTest/ShutdownJobTest.cs index d177b8c..0c41779 100644 --- a/AsyncSchedulerTest/ShutdownJobTest.cs +++ b/AsyncSchedulerTest/ShutdownJobTest.cs @@ -37,10 +37,10 @@ public async Task TestShutdown() private async Task RunScheduler(TimeSpan schedulerTime) { - CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); + var cancellationTokenSource = new CancellationTokenSource(); var schedulerTask = _scheduler.Start(cancellationTokenSource.Token); // ReSharper disable MethodSupportsCancellation - await Task.Delay(schedulerTime).ContinueWith((t) => cancellationTokenSource.Cancel()); + await Task.Delay(schedulerTime).ContinueWith(_ => cancellationTokenSource.Cancel()); var schedulerFinishTimeout = TimeSpan.FromSeconds(1); await Task.WhenAny(schedulerTask, Task.Delay(schedulerFinishTimeout)); cancellationTokenSource.Cancel(); diff --git a/AsyncSchedulerTest/TestData/NotImplementedSchedule.cs b/AsyncSchedulerTest/TestData/NotImplementedSchedule.cs index 2bbb10d..507a657 100644 --- a/AsyncSchedulerTest/TestData/NotImplementedSchedule.cs +++ b/AsyncSchedulerTest/TestData/NotImplementedSchedule.cs @@ -13,8 +13,8 @@ public NotImplementedSchedule(string marker) Marker = marker; } - public int GetExecutionPriority(string jobKey, IJobHistoryEntry lastExecution, IJobHistoryEntry lastSuccessfulExecution, - DateTime now) + public int GetExecutionPriority(string jobKey, IJobHistoryEntry? lastExecution, IJobHistoryEntry? lastSuccessfulExecution, + DateTimeOffset now) { throw new NotImplementedException(); } diff --git a/AsyncSchedulerTest/TestUtils/TestActivator.cs b/AsyncSchedulerTest/TestUtils/TestActivator.cs index 121d87a..b73c9c7 100644 --- a/AsyncSchedulerTest/TestUtils/TestActivator.cs +++ b/AsyncSchedulerTest/TestUtils/TestActivator.cs @@ -5,10 +5,10 @@ namespace AsyncSchedulerTest.TestUtils { public class TestActivator : IServiceProvider { - private readonly SimpleJob _simpleJobInstance; - private readonly ShutdownJob _shutdownJobInstance; + private readonly SimpleJob? _simpleJobInstance; + private readonly ShutdownJob? _shutdownJobInstance; - public TestActivator(SimpleJob simpleJobInstance = null, ShutdownJob shutdownJobInstance = null) + public TestActivator(SimpleJob? simpleJobInstance = null, ShutdownJob? shutdownJobInstance = null) { _simpleJobInstance = simpleJobInstance; _shutdownJobInstance = shutdownJobInstance; @@ -32,7 +32,7 @@ public object GetService(Type serviceType) { return _shutdownJobInstance; } - return Activator.CreateInstance(serviceType); + return Activator.CreateInstance(serviceType) ?? throw new InvalidOperationException("Unable to create object for type: " + serviceType); } } } \ No newline at end of file diff --git a/BlazorAppExample/BlazorAppExample.csproj.user b/BlazorAppExample/BlazorAppExample.csproj.user deleted file mode 100644 index c236719..0000000 --- a/BlazorAppExample/BlazorAppExample.csproj.user +++ /dev/null @@ -1,9 +0,0 @@ - - - - ProjectDebugger - - - BlazorAppExample - - \ No newline at end of file diff --git a/BlazorAppExample/Pages/Index.razor b/BlazorAppExample/Pages/Index.razor index f7de249..2e29740 100644 --- a/BlazorAppExample/Pages/Index.razor +++ b/BlazorAppExample/Pages/Index.razor @@ -19,7 +19,7 @@

Running Jobs

    - @foreach (var jobKey in Scheduler.CurrentlyRunningJobs) + @foreach (string jobKey in Scheduler.CurrentlyRunningJobs) {
  • Job: @jobKey
  • } diff --git a/BlazorAppExample/Program.cs b/BlazorAppExample/Program.cs index 6e0ccf8..b9a6591 100644 --- a/BlazorAppExample/Program.cs +++ b/BlazorAppExample/Program.cs @@ -1,16 +1,10 @@ -using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; using BlazorAppExample.BackgroundTasks; using Microsoft.Extensions.DependencyInjection; using Serilog; -using Serilog.Events; namespace BlazorAppExample { diff --git a/BlazorAppExample/Startup.cs b/BlazorAppExample/Startup.cs index 6b4224e..710d1df 100644 --- a/BlazorAppExample/Startup.cs +++ b/BlazorAppExample/Startup.cs @@ -1,16 +1,10 @@ using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using AsyncScheduler; using BlazorAppExample.BackgroundTasks; -using Serilog; namespace BlazorAppExample { diff --git a/ConsoleExample/JobRestrictions.cs b/ConsoleExample/JobRestrictions.cs index a002ea9..6c3cac5 100644 --- a/ConsoleExample/JobRestrictions.cs +++ b/ConsoleExample/JobRestrictions.cs @@ -1,6 +1,4 @@ -using System; using System.Collections.Generic; -using AsyncScheduler; using AsyncScheduler.Restrictions; namespace ConsoleExample diff --git a/ConsoleExample/Program.cs b/ConsoleExample/Program.cs index 6b5e777..868194b 100644 --- a/ConsoleExample/Program.cs +++ b/ConsoleExample/Program.cs @@ -8,6 +8,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Serilog; +using ILogger = Microsoft.Extensions.Logging.ILogger; namespace ConsoleExample { @@ -93,7 +94,7 @@ public static void Main(string[] args) } } - private static void ConsoleOnCancelKeyPress(object sender, ConsoleCancelEventArgs e, ILogger logger) + private static void ConsoleOnCancelKeyPress(object sender, ConsoleCancelEventArgs e, ILogger logger) { logger.LogInformation("Cancel Key was pressed. CancellationToken will be cancelled"); _cancellationTokenSource.Cancel();