Skip to content

Commit

Permalink
Merge pull request #20 from badatgaems/timezone-config-override
Browse files Browse the repository at this point in the history
Pulling timezoneInfo from TimezoneId provided in config as well as ne…
  • Loading branch information
maitlandmarshall authored Nov 6, 2023
2 parents 47c1558 + 676ae9e commit ec28e89
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 23 deletions.
8 changes: 4 additions & 4 deletions MIFCore.Hangfire/IRecurringJobManagerExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,24 @@ namespace MIFCore.Hangfire
{
public static class IRecurringJobManagerExtensions
{
public static void CreateRecurringJob(this IRecurringJobManager recurringJobManager, string jobName, Expression<Func<Task>> methodCall, string cronSchedule = null, string queue = "default", bool triggerIfNeverExecuted = false)
public static void CreateRecurringJob(this IRecurringJobManager recurringJobManager, string jobName, Expression<Func<Task>> methodCall, string cronSchedule = null, string queue = "default", bool triggerIfNeverExecuted = false, TimeZoneInfo timeZone = null)
{
var manager = recurringJobManager as MIFCoreRecurringJobManager;

if (manager is null)
throw new ArgumentException("Parameter 'recurringJobManager' is not of type 'MIFCore.Hangfire.MIFCoreRecurringJobManager'");

manager.CreateRecurringJob(jobName: jobName, methodCall: methodCall, cronSchedule: cronSchedule, queue: queue, triggerIfNeverExecuted: triggerIfNeverExecuted);
manager.CreateRecurringJob(jobName: jobName, methodCall: methodCall, cronSchedule: cronSchedule, queue: queue, triggerIfNeverExecuted: triggerIfNeverExecuted, timeZone: timeZone);
}

public static void CreateRecurringJob<T>(this IRecurringJobManager recurringJobManager, string jobName, Expression<Func<T, Task>> methodCall, string cronSchedule = null, string queue = "default", bool triggerIfNeverExecuted = false)
public static void CreateRecurringJob<T>(this IRecurringJobManager recurringJobManager, string jobName, Expression<Func<T, Task>> methodCall, string cronSchedule = null, string queue = "default", bool triggerIfNeverExecuted = false, TimeZoneInfo timeZone = null)
{
var manager = recurringJobManager as MIFCoreRecurringJobManager;

if (manager is null)
throw new ArgumentException("Parameter 'recurringJobManager' is not of type 'MIFCore.Hangfire.MIFCoreRecurringJobManager'");

manager.CreateRecurringJob<T>(jobName: jobName, methodCall: methodCall, cronSchedule: cronSchedule, queue: queue, triggerIfNeverExecuted: triggerIfNeverExecuted);
manager.CreateRecurringJob<T>(jobName: jobName, methodCall: methodCall, cronSchedule: cronSchedule, queue: queue, triggerIfNeverExecuted: triggerIfNeverExecuted, timeZone: timeZone);
}
}
}
70 changes: 58 additions & 12 deletions MIFCore.Hangfire/MIFCoreRecurringJobManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,33 +22,35 @@ public MIFCoreRecurringJobManager(JobStorage jobStorage)
this.jobStorage = jobStorage;
}

public void CreateRecurringJob<T>(string jobName, Expression<Func<T, Task>> methodCall, string cronSchedule = null, string queue = "default", bool triggerIfNeverExecuted = false)
public void CreateRecurringJob<T>(string jobName, Expression<Func<T, Task>> methodCall, string cronSchedule = null, string queue = "default", bool triggerIfNeverExecuted = false, TimeZoneInfo timeZone = null)
{
timeZone = this.GetTimeZoneInfo(jobName, timeZone);
cronSchedule = this.GetCronSchedule(jobName, cronSchedule);

var job = Job.FromExpression(methodCall);

this.recurringJobManager.AddOrUpdate<T>(
recurringJobId: jobName,
methodCall: methodCall,
cronExpression: cronSchedule,
timeZone: TimeZoneInfo.Local,
queue: queue);
timeZone: timeZone,
queue: queue
);

if (triggerIfNeverExecuted)
this.TriggerRecurringJobIfNeverExecuted(jobName);
}

public void CreateRecurringJob(string jobName, Expression<Func<Task>> methodCall, string cronSchedule = null, string queue = "default", bool triggerIfNeverExecuted = false)
public void CreateRecurringJob(string jobName, Expression<Func<Task>> methodCall, string cronSchedule = null, string queue = "default", bool triggerIfNeverExecuted = false, TimeZoneInfo timeZone = null)
{
timeZone = this.GetTimeZoneInfo(jobName, timeZone);
cronSchedule = this.GetCronSchedule(jobName, cronSchedule);

this.recurringJobManager.AddOrUpdate(
recurringJobId: jobName,
methodCall: methodCall,
cronExpression: cronSchedule,
timeZone: TimeZoneInfo.Local,
queue: queue);
recurringJobId: jobName,
methodCall: methodCall,
cronExpression: cronSchedule,
timeZone: timeZone,
queue: queue
);

if (triggerIfNeverExecuted)
this.TriggerRecurringJobIfNeverExecuted(jobName);
Expand All @@ -70,11 +72,55 @@ public string GetCronSchedule(string jobName, string cronSchedule = null)
}

private string GetCronFromConfig(string jobName)
{
{
var section = Globals.DefaultConfiguration.GetSection(jobName);

// check if the config value has sub keys for "cron" instead of being set directly on the jobName key.
var cronSubKey = section.GetSection("cron");
if (cronSubKey.Exists())
{
return cronSubKey.Value;
}

return section.Exists() ? section.Value : null;
}

/// <summary>
/// Retreives the TimeZoneInfo for the jobName from the config file or returns the passed value if not found.
/// If no value is passed, the default TimeZoneInfo.Local is returned.
/// </summary>
/// <param name="jobName"></param>
/// <param name="timeZoneInfo"></param>
/// <returns></returns>
public TimeZoneInfo GetTimeZoneInfo(string jobName, TimeZoneInfo timeZoneInfo = null)
{
// try get config value
var configOverride = this.GetTimeZoneInfoFromConfig(jobName);

// prefer config > code configured tz > default tz
return configOverride ?? timeZoneInfo ?? TimeZoneInfo.Local;
}

/// <summary>
/// Check for the existence of a timezone config value for the jobName.
/// in .Net 5 the only supported timzone Ids can be found with "tzutil /l" on command line for windows;
/// </summary>
/// <param name="jobName"></param>
/// <returns></returns>
private TimeZoneInfo GetTimeZoneInfoFromConfig(string jobName)
{
var section = Globals.DefaultConfiguration.GetSection(jobName);
var tzInfoSubKey = section.GetSection("timezone");

// exit early if key doesn't exist or has an empty value.
if (!tzInfoSubKey.Exists() || string.IsNullOrWhiteSpace(tzInfoSubKey.Value))
{
return null;
}

return TimeZoneInfo.FindSystemTimeZoneById(tzInfoSubKey.Value);
}

private void TriggerRecurringJobIfNeverExecuted(string jobName)
{
var connection = this.jobStorage.GetConnection();
Expand Down
4 changes: 2 additions & 2 deletions MIFCore.TestApp/MIFCore.TestApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand All @@ -15,7 +15,7 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

Expand Down
9 changes: 9 additions & 0 deletions MIFCore.TestApp/SomeJob.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Hangfire;
using Hangfire.Annotations;
using MIFCore.Hangfire;
using System;
using System.Threading.Tasks;
Expand Down Expand Up @@ -26,6 +27,14 @@ public Task DoTheJob()
return Task.CompletedTask;
}

public Task DingleDog([NotNull] string dingledog) {
var current = BackgroundJobContext.Current;

Console.WriteLine($"dingledog: {dingledog}");

return Task.CompletedTask;
}

public Task TriggeredJobAction()
{
Console.WriteLine("triggered job action");
Expand Down
11 changes: 10 additions & 1 deletion MIFCore.TestApp/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Hangfire;
using MIFCore.Hangfire;
using Microsoft.Extensions.DependencyInjection;
using System;

namespace MIFCore.TestApp
{
Expand All @@ -10,6 +11,8 @@ public void ConfigureServices(IServiceCollection serviceDescriptors)
{
serviceDescriptors.AddScoped<SomeJob>();
serviceDescriptors.AddControllers();


}

public void Configure()
Expand All @@ -19,7 +22,13 @@ public void Configure()

public void PostConfigure(IBackgroundJobClient backgroundJobClient, IRecurringJobManager recurringJobManager)
{
recurringJobManager.CreateRecurringJob<SomeJob>("some-job", y => y.DoTheJob(), Cron.Monthly());
recurringJobManager.CreateRecurringJob<SomeJob>("some-job", y => y.DoTheJob(), cronSchedule: "*/5 * * * *");
recurringJobManager.CreateRecurringJob<SomeJob>("some-goober-boy", y => y.DingleDog("goober"), cronSchedule: "*/5 * * * *");

// This doesn't seem to run due to the queue?
recurringJobManager.CreateRecurringJob<SomeJob>("some-bigboi", y => y.DingleDog("biggest-boi"), cronSchedule: "*/5 * * * *", queue: "bigboi");


recurringJobManager.CreateRecurringJob<SomeJob>("some-job-triggered", y => y.TriggeredJobAction(), Cron.Monthly());

backgroundJobClient.Enqueue<SomeJob>(y => y.DoTheJob());
Expand Down
16 changes: 12 additions & 4 deletions MIFCore.TestApp/settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
{
"connectionString": "",
"bindingPort": 80,
"bindingPath": "abc",
"instrumentationKey": ""

"bindingPort": 1337,
"bindingPath": "",
"instrumentationKey": "",
"some-job": "* * * * *",
"some-goober-boy": {
"cron": "* * * * *",
"timezone": "Bougainville Standard Time"
},
"some-bigboi": {
"cron": "* * * * *",
"timezone": "Samoa Standard Time"
}
}

0 comments on commit ec28e89

Please sign in to comment.