Skip to content

Commit

Permalink
Don't run cron jobs a bunch of times in a row when we miss multiple i…
Browse files Browse the repository at this point in the history
…terations
  • Loading branch information
ejsmith committed Oct 13, 2024
1 parent b851839 commit 0800eb6
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 20 deletions.
2 changes: 1 addition & 1 deletion samples/Foundatio.HostingSample/Jobs/Sample2Job.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace Foundatio.HostingSample;

[Job(Description = "Sample 2 job", Interval = "2s", IterationLimit = 10)]
[Job(Description = "Sample 2 job", Interval = "15s", IterationLimit = 24)]
public class Sample2Job : IJob, IHealthCheck
{
private readonly ILogger _logger;
Expand Down
6 changes: 3 additions & 3 deletions samples/Foundatio.HostingSample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public static IHostBuilder CreateHostBuilder(string[] args)
// gets inserted as 1st startup action so that any other startup actions dont run until the critical resources are available
s.AddStartupActionToWaitForHealthChecks("Critical");

s.AddHealthChecks().AddCheck<MyCriticalHealthCheck>("My Critical Resource", tags: new[] { "Critical" });
s.AddHealthChecks().AddCheck<MyCriticalHealthCheck>("My Critical Resource", tags: ["Critical"]);

// add health check that does not return healthy until the startup actions have completed
// useful for readiness checks
Expand All @@ -122,12 +122,12 @@ public static IHostBuilder CreateHostBuilder(string[] args)
});

if (sample1)
s.AddJob("Sample1", sp => new Sample1Job(sp.GetRequiredService<ILoggerFactory>()), o => o.ApplyDefaults<Sample1Job>().WaitForStartupActions(true).InitialDelay(TimeSpan.FromSeconds(4)));
s.AddJob("Sample1", sp => new Sample1Job(sp.GetRequiredService<ILoggerFactory>()), o => o.ApplyDefaults<Sample1Job>().WaitForStartupActions().InitialDelay(TimeSpan.FromSeconds(4)));

if (sample2)
{
s.AddHealthChecks().AddCheck<Sample2Job>("Sample2Job");
s.AddJob<Sample2Job>(o => o.WaitForStartupActions(true));
s.AddJob<Sample2Job>(o => o.WaitForStartupActions());
}

// if you don't specify priority, actions will automatically be assigned an incrementing priority starting at 0
Expand Down
11 changes: 9 additions & 2 deletions samples/Foundatio.HostingSample/Startup/MyStartupAction.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Threading;
using System;
using System.Threading;
using System.Threading.Tasks;
using Foundatio.Caching;
using Foundatio.Extensions.Hosting.Jobs;
using Foundatio.Extensions.Hosting.Startup;
using Microsoft.Extensions.Logging;
Expand All @@ -9,16 +11,21 @@ namespace Foundatio.HostingSample;
public class MyStartupAction : IStartupAction
{
private readonly IJobManager _jobManager;
private readonly ICacheClient _cacheClient;
private readonly ILogger _logger;

public MyStartupAction(IJobManager jobManager, ILogger<MyStartupAction> logger)
public MyStartupAction(IJobManager jobManager, ICacheClient cacheClient, ILogger<MyStartupAction> logger)
{
_jobManager = jobManager;
_cacheClient = cacheClient;
_logger = logger;
}

public async Task RunAsync(CancellationToken cancellationToken = default)
{
// simulate a long period of time since our last cron job run
await _cacheClient.SetAsync("jobs:lastrun:Foundatio.HostingSample.EveryMinuteJob", DateTime.UtcNow.AddDays(-1));

for (int i = 0; i < 5; i++)
{
_logger.LogTrace("MyStartupAction Run Thread={ManagedThreadId}", Thread.CurrentThread.ManagedThreadId);
Expand Down
15 changes: 1 addition & 14 deletions src/Foundatio.Extensions.Hosting/Jobs/ScheduledJobRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ internal class ScheduledJobRunner
private readonly ILockProvider _lockProvider;
private readonly ILogger _logger;
private readonly DateTime _baseDate = new(2010, 1, 1);
private bool _lastRunChecked = false;
private DateTime _lastStatusUpdate = DateTime.MinValue;

public ScheduledJobRunner(ScheduledJobOptions jobOptions, IServiceProvider serviceProvider, ICacheClient cacheClient, ILoggerFactory loggerFactory = null)
Expand Down Expand Up @@ -76,18 +75,6 @@ public string Schedule

public async ValueTask<bool> ShouldRunAsync()
{
// get initial last run value
if (!_lastRunChecked && !LastRun.HasValue)
{
var lastRun = await _cacheClient.GetAsync<DateTime>("lastrun:" + Options.Name).AnyContext();
if (lastRun.HasValue)
{
LastRun = lastRun.Value;
NextRun = _cronSchedule.GetNextOccurrence(LastRun.Value);
}
_lastRunChecked = true;
}

if (_timeProvider.GetUtcNow().UtcDateTime.Subtract(_lastStatusUpdate).TotalSeconds > 15)
{
var lastRun = await _cacheClient.GetAsync<DateTime>("lastrun:" + Options.Name).AnyContext();
Expand Down Expand Up @@ -183,7 +170,7 @@ public async Task StartAsync(CancellationToken cancellationToken = default)
}
}, cancellationToken).Unwrap();

LastRun = NextRun;
LastRun = _timeProvider.GetUtcNow().UtcDateTime;
await _cacheClient.SetAsync("lastrun:" + Options.Name, LastRun.Value).AnyContext();
NextRun = _cronSchedule.GetNextOccurrence(LastRun.Value);
}
Expand Down

0 comments on commit 0800eb6

Please sign in to comment.