refactor(dotnet): standardize scheduler state and definitions
This commit is contained in:
@@ -73,6 +73,20 @@ public class SchedulerServiceTests
|
||||
), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetRecurringJobDefinitions_ReturnsCanonicalDefinitions()
|
||||
{
|
||||
var service = CreateService();
|
||||
|
||||
var defs = service.GetRecurringJobDefinitions();
|
||||
|
||||
Assert.Equal(4, defs.Count);
|
||||
Assert.Contains(defs, d => d.JobId == "daily-collection" && d.IsRecurring);
|
||||
Assert.Contains(defs, d => d.JobId == "hourly-price-update" && d.IsRecurring);
|
||||
Assert.Contains(defs, d => d.JobId == "weekly-report" && d.IsRecurring);
|
||||
Assert.Contains(defs, d => d.JobId == "monthly-optimization" && d.IsRecurring);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadTickersFromJson_WhenFileMissing_FallsBackToDefaultUniverse()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
namespace QuantEngine.Web.Services;
|
||||
|
||||
public sealed record SchedulerJobDefinition(
|
||||
string JobId,
|
||||
string Cron,
|
||||
string Description,
|
||||
bool IsRecurring);
|
||||
|
||||
public sealed record SchedulerJobExecutionAudit(
|
||||
string JobId,
|
||||
string RunId,
|
||||
string State,
|
||||
string? Reason,
|
||||
DateTimeOffset StartedAt,
|
||||
DateTimeOffset? FinishedAt,
|
||||
string? ResourceKey);
|
||||
|
||||
public static class SchedulerStates
|
||||
{
|
||||
public const string Pending = "PENDING";
|
||||
public const string Running = "RUNNING";
|
||||
public const string Succeeded = "SUCCEEDED";
|
||||
public const string Failed = "FAILED";
|
||||
public const string Retrying = "RETRYING";
|
||||
public const string Blocked = "BLOCKED";
|
||||
}
|
||||
@@ -16,12 +16,6 @@ namespace QuantEngine.Web.Services;
|
||||
/// </summary>
|
||||
public class SchedulerService
|
||||
{
|
||||
private sealed record RecurringJobDefinition(
|
||||
string JobId,
|
||||
Expression<Func<Task>> Job,
|
||||
string Cron,
|
||||
string Description);
|
||||
|
||||
private readonly ILogger<SchedulerService> _logger;
|
||||
private readonly IBackgroundJobClient _jobClient;
|
||||
private readonly IRecurringJobManager _recurringJobManager;
|
||||
@@ -82,12 +76,12 @@ public class SchedulerService
|
||||
}
|
||||
}
|
||||
|
||||
private IReadOnlyList<RecurringJobDefinition> BuildRecurringJobs() => new[]
|
||||
public IReadOnlyList<SchedulerJobDefinition> GetRecurringJobDefinitions() => new[]
|
||||
{
|
||||
new RecurringJobDefinition("daily-collection", () => RunDailyCollectionAsync(), "0 9 * * *", "Daily data collection"),
|
||||
new RecurringJobDefinition("hourly-price-update", () => UpdatePricesAsync(), "0 9,11,13,15 * * 1-5", "Hourly price update"),
|
||||
new RecurringJobDefinition("weekly-report", () => GenerateWeeklyReportAsync(), "0 17 * * 5", "Weekly report generation"),
|
||||
new RecurringJobDefinition("monthly-optimization", () => RunMonthlyOptimizationAsync(), "0 2 1 * *", "Monthly optimization"),
|
||||
new SchedulerJobDefinition("daily-collection", "0 9 * * *", "Daily data collection", true),
|
||||
new SchedulerJobDefinition("hourly-price-update", "0 9,11,13,15 * * 1-5", "Hourly price update", true),
|
||||
new SchedulerJobDefinition("weekly-report", "0 17 * * 5", "Weekly report generation", true),
|
||||
new SchedulerJobDefinition("monthly-optimization", "0 2 1 * *", "Monthly optimization", true),
|
||||
};
|
||||
|
||||
private static string? FindGatherTradingDataJson()
|
||||
@@ -118,11 +112,11 @@ public class SchedulerService
|
||||
{
|
||||
_logger.LogInformation("Initializing Hangfire schedules...");
|
||||
|
||||
foreach (var job in BuildRecurringJobs())
|
||||
foreach (var job in GetRecurringJobDefinitions())
|
||||
{
|
||||
_recurringJobManager.AddOrUpdate(
|
||||
job.JobId,
|
||||
job.Job,
|
||||
ResolveRecurringJob(job.JobId),
|
||||
job.Cron,
|
||||
new RecurringJobOptions { TimeZone = TimeZoneInfo.Local }
|
||||
);
|
||||
@@ -279,6 +273,15 @@ public class SchedulerService
|
||||
return JobStorage.Current.GetConnection().GetJobData(jobId)?.State;
|
||||
}
|
||||
|
||||
private Expression<Func<Task>> ResolveRecurringJob(string jobId) => jobId switch
|
||||
{
|
||||
"daily-collection" => () => RunDailyCollectionAsync(),
|
||||
"hourly-price-update" => () => UpdatePricesAsync(),
|
||||
"weekly-report" => () => GenerateWeeklyReportAsync(),
|
||||
"monthly-optimization" => () => RunMonthlyOptimizationAsync(),
|
||||
_ => throw new InvalidOperationException($"Unknown recurring job id: {jobId}")
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Cancel scheduled job
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user