Files
2025-11-20 09:04:45 -05:00

99 lines
3.6 KiB
C#

using System.Data;
using FictionArchive.Service.SchedulerService.Models;
using FictionArchive.Service.SchedulerService.Models.JobTemplates;
using FictionArchive.Service.Shared.Services.EventBus;
using Quartz;
using Quartz.Impl.Matchers;
namespace FictionArchive.Service.SchedulerService.Services;
public class JobManagerService
{
private readonly ILogger<JobManagerService> _logger;
private readonly ISchedulerFactory _schedulerFactory;
public JobManagerService(ILogger<JobManagerService> logger, ISchedulerFactory schedulerFactory)
{
_logger = logger;
_schedulerFactory = schedulerFactory;
}
public async Task<List<SchedulerJob>> GetScheduledJobs()
{
var scheduler = await _schedulerFactory.GetScheduler();
var groups = await scheduler.GetJobGroupNames();
var result = new List<(IJobDetail Job, IReadOnlyCollection<ITrigger> Triggers)>();
foreach (var group in groups)
{
var jobKeys = await scheduler.GetJobKeys(GroupMatcher<JobKey>.GroupEquals(group));
foreach (var jobKey in jobKeys)
{
var jobDetail = await scheduler.GetJobDetail(jobKey);
var triggers = await scheduler.GetTriggersOfJob(jobKey);
result.Add((jobDetail, triggers));
}
}
return result.Select(tuple => new SchedulerJob()
{
JobKey = tuple.Job.Key,
Description = tuple.Job.Description,
JobTypeName = tuple.Job.JobType.FullName,
JobData = tuple.Job.JobDataMap.ToDictionary(kv => kv.Key, kv => kv.Value.ToString()),
CronSchedule = tuple.Triggers.Where(trigger => trigger is ICronTrigger).Select(trigger => (trigger as ICronTrigger).CronExpressionString).ToList()
}).ToList();
}
public async Task<SchedulerJob> ScheduleEventJob(string? jobKey, string? description, string eventType, string eventData, string cronSchedule)
{
var scheduler = await _schedulerFactory.GetScheduler();
if (await scheduler.GetJobDetail(new JobKey(jobKey)) != null)
{
throw new DuplicateNameException("A job with the same key already exists.");
}
jobKey ??= Guid.NewGuid().ToString();
var jobData = new JobDataMap
{
{ EventJobTemplate.EventTypeParameter, eventType },
{ EventJobTemplate.EventDataParameter, eventData }
};
var job = JobBuilder.Create<EventJobTemplate>()
.WithIdentity(jobKey)
.WithDescription(description ?? $"Fires off an event on a set schedule")
.SetJobData(jobData)
.Build();
var trigger = TriggerBuilder.Create()
.WithIdentity(jobKey)
.WithCronSchedule(cronSchedule)
.StartNow()
.Build();
await scheduler.ScheduleJob(job, trigger);
return new SchedulerJob()
{
CronSchedule = new List<string> { cronSchedule },
Description = description,
JobKey = new JobKey(jobKey),
JobTypeName = typeof(EventJobTemplate).FullName,
JobData = jobData.ToDictionary(kv => kv.Key, kv => kv.Value.ToString())
};
}
public async Task<bool> TriggerJob(string jobKey)
{
var scheduler = await _schedulerFactory.GetScheduler();
await scheduler.TriggerJob(new JobKey(jobKey));
return true;
}
public async Task<bool> DeleteJob(string jobKey)
{
var scheduler = await _schedulerFactory.GetScheduler();
return await scheduler.DeleteJob(new JobKey(jobKey));
}
}