mirror of
https://github.com/kevincolyar/CronNET.git
synced 2024-05-17 05:02:35 +02:00
Fixed semaphore not being released.
Added delay until next minute. Updated how the option setup works.
This commit is contained in:
parent
e3d387b2cd
commit
700bf3abe3
|
@ -1,18 +1,21 @@
|
|||
using crondotnet;
|
||||
using crondotnet.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
public static class CronServiceProverExtensions
|
||||
{
|
||||
public static IServiceCollection AddCron(this IServiceCollection services, Action<ICronDaemonOptionsBuilder>? optionsAction = null)
|
||||
public static IServiceCollection AddCron(this IServiceCollection services, Action<ICronDaemonOptionsBuilder>? cronBuilder = null)
|
||||
{
|
||||
services.AddSingleton<CronDaemonHostedService>();
|
||||
services.AddHostedService<CronDaemonHostedService>();
|
||||
services.AddScoped<ICronDaemon, CronDaemon>();
|
||||
|
||||
var cronDaemonOptionsBuilder = new CronDaemonOptionsBuilder();
|
||||
optionsAction?.Invoke(cronDaemonOptionsBuilder);
|
||||
services.ConfigureOptions(cronDaemonOptionsBuilder.Build());
|
||||
var cronDaemonOptionsBuilder = new CronDaemonOptionsBuilder(services);
|
||||
cronBuilder?.Invoke(cronDaemonOptionsBuilder);
|
||||
|
||||
services.AddOptions<CronDaemonOptions>()
|
||||
.Configure(options => cronDaemonOptionsBuilder.Bind(options));
|
||||
|
||||
return services;
|
||||
}
|
||||
|
@ -27,11 +30,17 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
|
||||
public class CronDaemonOptionsBuilder : ICronDaemonOptionsBuilder
|
||||
{
|
||||
private readonly CronDaemonOptions Options = new CronDaemonOptions();
|
||||
private readonly List<JobOptions> Jobs = new List<JobOptions>();
|
||||
private IServiceCollection services;
|
||||
|
||||
public CronDaemonOptionsBuilder(IServiceCollection services)
|
||||
{
|
||||
this.services = services;
|
||||
}
|
||||
|
||||
public ICronDaemonOptionsBuilder AddJob(string cronExpression, ExecuteCronJob job)
|
||||
{
|
||||
Options.Jobs.Add(new JobOptions
|
||||
Jobs.Add(new JobOptions
|
||||
{
|
||||
Expression = cronExpression,
|
||||
StaticTask = job
|
||||
|
@ -43,18 +52,23 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
public ICronDaemonOptionsBuilder AddJob<TService>(string cronExpression)
|
||||
where TService : IThinService
|
||||
{
|
||||
Options.Jobs.Add(new JobOptions
|
||||
Jobs.Add(new JobOptions
|
||||
{
|
||||
Expression = cronExpression,
|
||||
ServiceType = typeof(TService),
|
||||
});
|
||||
|
||||
services.TryAddScoped(typeof(TService));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
internal CronDaemonOptions Build()
|
||||
internal void Bind(CronDaemonOptions options)
|
||||
{
|
||||
return Options;
|
||||
foreach (var job in Jobs)
|
||||
{
|
||||
options.Jobs.Add(job);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,7 +16,6 @@ namespace crondotnet
|
|||
{
|
||||
private readonly PeriodicTimer timer;
|
||||
private readonly List<ICronJob> cronJobs = new List<ICronJob>();
|
||||
private DateTime _last = DateTime.Now;
|
||||
private CancellationTokenSource tokenSource = null;
|
||||
private Task timerTask = null;
|
||||
|
||||
|
@ -50,18 +49,27 @@ namespace crondotnet
|
|||
|
||||
private async Task InternalStart(CancellationToken cancellationToken)
|
||||
{
|
||||
var currentTime = DateTime.Now;
|
||||
var targetTime = currentTime.Date.AddHours(currentTime.Hour).AddMinutes(currentTime.Minute + 1);
|
||||
// .AddSeconds(currentTime.Second + (30 - (currentTime.Second % 30))); // If we wanted to increase resolution, this would allow for specify second targetting.
|
||||
|
||||
DateTime? lastRun = null;
|
||||
|
||||
// wait until the next 30 second interval before starting to trigger.
|
||||
await Task.Delay(targetTime - currentTime);
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
await timer.WaitForNextTickAsync(cancellationToken);
|
||||
|
||||
if (!cancellationToken.IsCancellationRequested && DateTime.Now.Minute != _last.Minute)
|
||||
if (!cancellationToken.IsCancellationRequested && (!lastRun.HasValue || DateTime.Now.Minute != lastRun.Value.Minute))
|
||||
{
|
||||
_last = DateTime.Now;
|
||||
lastRun = DateTime.Now;
|
||||
foreach (ICronJob job in cronJobs)
|
||||
job.Execute(DateTime.Now, cancellationToken);
|
||||
job.Execute(lastRun.Value, cancellationToken);
|
||||
}
|
||||
|
||||
await timer.WaitForNextTickAsync(cancellationToken);
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
{
|
||||
|
|
|
@ -25,12 +25,19 @@ namespace crondotnet
|
|||
|
||||
public async Task Execute(DateTime startTime, CancellationToken cancellationToken)
|
||||
{
|
||||
await _semaphore.WaitAsync(cancellationToken);
|
||||
try
|
||||
{
|
||||
await _semaphore.WaitAsync(cancellationToken);
|
||||
|
||||
if (!_cronSchedule.IsTime(startTime))
|
||||
return;
|
||||
if (!_cronSchedule.IsTime(startTime))
|
||||
return;
|
||||
|
||||
await _threadStart(cancellationToken);
|
||||
await _threadStart(cancellationToken);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_semaphore.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user