Skip to content

Commit

Permalink
Various improvements to hosting scheduled jobs (#304)
Browse files Browse the repository at this point in the history
* Various improvements to hosting scheduled jobs

* Extract ScheduledJobManager interface

* Changes based on feedback

* Move Cronos to Foundatio namespace to prevent collisions.

* Update error message to include job name
  • Loading branch information
ejsmith authored Jul 26, 2024
1 parent d75c9e8 commit 958435a
Show file tree
Hide file tree
Showing 27 changed files with 644 additions and 246 deletions.
27 changes: 0 additions & 27 deletions samples/Foundatio.HostingSample/Jobs/EvenMinutesJob.cs

This file was deleted.

17 changes: 13 additions & 4 deletions samples/Foundatio.HostingSample/Program.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Foundatio.Extensions.Hosting.Jobs;
using Foundatio.Extensions.Hosting.Startup;
using Foundatio.Jobs;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
Expand Down Expand Up @@ -87,18 +89,25 @@ public static IHostBuilder CreateHostBuilder(string[] args)
s.AddHealthChecks().AddCheckForStartupActions("Critical");

if (everyMinute)
s.AddCronJob<EveryMinuteJob>("* * * * *");
s.AddDistributedCronJob<EveryMinuteJob>("* * * * *");

if (evenMinutes)
s.AddCronJob<EvenMinutesJob>("*/2 * * * *");
s.AddCronJob("EvenMinutes", "*/2 * * * *", async sp =>
{
var logger = sp.GetRequiredService<ILogger<Program>>();
if (logger.IsEnabled(LogLevel.Information))
logger.LogInformation("EvenMinuteJob Run Thread={ManagedThreadId}", Thread.CurrentThread.ManagedThreadId);

await Task.Delay(TimeSpan.FromSeconds(5));
});

if (sample1)
s.AddJob(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(true).InitialDelay(TimeSpan.FromSeconds(4)));

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

// if you don't specify priority, actions will automatically be assigned an incrementing priority starting at 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"profiles": {
"Foundatio.HostingSample": {
"commandName": "Project",
"commandLineArgs": "sample1 sample2"
"commandLineArgs": "all"
}
}
}
12 changes: 11 additions & 1 deletion samples/Foundatio.HostingSample/Startup/MyStartupAction.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
using System.Threading;
using System.Threading.Tasks;
using Foundatio.Extensions.Hosting.Jobs;
using Foundatio.Extensions.Hosting.Startup;
using Microsoft.Extensions.Logging;

namespace Foundatio.HostingSample;

public class MyStartupAction : IStartupAction
{
private readonly IScheduledJobManager _scheduledJobManager;
private readonly ILogger _logger;

public MyStartupAction(ILogger<MyStartupAction> logger)
public MyStartupAction(IScheduledJobManager scheduledJobManager, ILogger<MyStartupAction> logger)
{
_scheduledJobManager = scheduledJobManager;
_logger = logger;
}

Expand All @@ -21,5 +24,12 @@ public async Task RunAsync(CancellationToken cancellationToken = default)
_logger.LogTrace("MyStartupAction Run Thread={ManagedThreadId}", Thread.CurrentThread.ManagedThreadId);
await Task.Delay(500);
}

_scheduledJobManager.AddOrUpdate("MyJob", "* * * * *", async () =>
{
_logger.LogInformation("Running MyJob");
await Task.Delay(1000);
_logger.LogInformation("MyJob Complete");
});
}
}
2 changes: 1 addition & 1 deletion src/Foundatio.Extensions.Hosting/Cronos/CalendarHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using System;
using System.Runtime.CompilerServices;

namespace Cronos;
namespace Foundatio.Extensions.Hosting.Cronos;

internal static class CalendarHelper
{
Expand Down
2 changes: 1 addition & 1 deletion src/Foundatio.Extensions.Hosting/Cronos/CronExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
using System.Runtime.CompilerServices;
using System.Text;

namespace Cronos;
namespace Foundatio.Extensions.Hosting.Cronos;

/// <summary>
/// Provides a parser and scheduler for cron expressions.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

using System;

namespace Cronos;
namespace Foundatio.Extensions.Hosting.Cronos;

[Flags]
internal enum CronExpressionFlag : byte
Expand Down
2 changes: 1 addition & 1 deletion src/Foundatio.Extensions.Hosting/Cronos/CronField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

namespace Cronos;
namespace Foundatio.Extensions.Hosting.Cronos;

internal sealed class CronField
{
Expand Down
2 changes: 1 addition & 1 deletion src/Foundatio.Extensions.Hosting/Cronos/CronFormat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

using System;

namespace Cronos;
namespace Foundatio.Extensions.Hosting.Cronos;

/// <summary>
/// Defines the cron format options that customize string parsing for <see cref="CronExpression.Parse(string, CronFormat)"/>.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

using System;

namespace Cronos;
namespace Foundatio.Extensions.Hosting.Cronos;

/// <summary>
/// Represents an exception that's thrown, when invalid Cron expression is given.
Expand Down
2 changes: 1 addition & 1 deletion src/Foundatio.Extensions.Hosting/Cronos/TimeZoneHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

using System;

namespace Cronos;
namespace Foundatio.Extensions.Hosting.Cronos;

internal static class TimeZoneHelper
{
Expand Down
26 changes: 26 additions & 0 deletions src/Foundatio.Extensions.Hosting/Jobs/DynamicJob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Foundatio.Jobs;
using Foundatio.Utility;

namespace Foundatio.Extensions.Hosting.Jobs;

internal class DynamicJob : IJob
{
private readonly IServiceProvider _serviceProvider;
private readonly Func<IServiceProvider, CancellationToken, Task> _action;

public DynamicJob(IServiceProvider serviceProvider, Func<IServiceProvider, CancellationToken, Task> action)
{
_serviceProvider = serviceProvider;
_action = action;
}

public async Task<JobResult> RunAsync(CancellationToken cancellationToken = default)
{
await _action(_serviceProvider, cancellationToken).AnyContext();

return JobResult.Success;
}
}
1 change: 0 additions & 1 deletion src/Foundatio.Extensions.Hosting/Jobs/HostedJobOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@ namespace Foundatio.Extensions.Hosting.Jobs;
public class HostedJobOptions : JobOptions
{
public bool WaitForStartupActions { get; set; }
public string CronSchedule { get; set; }
}
5 changes: 4 additions & 1 deletion src/Foundatio.Extensions.Hosting/Jobs/HostedJobService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Foundatio.Extensions.Hosting.Startup;
Expand Down Expand Up @@ -47,10 +48,12 @@ private async Task ExecuteAsync(CancellationToken stoppingToken)
}
}

var runner = new JobRunner(_jobOptions, _loggerFactory);
var runner = new JobRunner(_jobOptions, _serviceProvider, _loggerFactory);

try
{
using var activity = FoundatioDiagnostics.ActivitySource.StartActivity("Job " + _jobOptions.Name, ActivityKind.Server);

await runner.RunAsync(stoppingToken).AnyContext();
#if NET8_0_OR_GREATER
await _stoppingCts.CancelAsync().AnyContext();
Expand Down
Loading

0 comments on commit 958435a

Please sign in to comment.