BotSharp/src/Infrastructure/BotSharp.Core.Crontab/Services/CrontabWatcher.cs

81 lines
2.7 KiB
C#
Raw Normal View History

2024-12-03 22:52:14 +00:00
using BotSharp.Abstraction.Infrastructures;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NCrontab;
namespace BotSharp.Core.Crontab.Services;
public class CrontabWatcher : BackgroundService
{
private readonly ILogger _logger;
private readonly IServiceProvider _services;
public CrontabWatcher(IServiceProvider services, ILogger<CrontabWatcher> logger)
{
_logger = logger;
_services = services;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Crontab Watcher background service is running.");
using (var scope = _services.CreateScope())
{
var locker = scope.ServiceProvider.GetRequiredService<IDistributedLocker>();
while (!stoppingToken.IsCancellationRequested)
{
var delay = Task.Delay(1000, stoppingToken);
await locker.LockAsync("CrontabWatcher", async () =>
{
await RunCronChecker(scope.ServiceProvider);
});
await delay;
}
_logger.LogWarning("Crontab Watcher background service is stopped.");
}
}
private async Task RunCronChecker(IServiceProvider services)
{
var cron = services.GetRequiredService<ICrontabService>();
var crons = await cron.GetCrontable();
foreach (var item in crons)
{
2024-12-10 21:16:03 +00:00
try
2024-12-03 22:52:14 +00:00
{
2024-12-11 22:02:22 +00:00
// strip seconds from cron expression
item.Cron = string.Join(" ", item.Cron.Split(' ').TakeLast(5));
2024-12-10 21:16:03 +00:00
var schedule = CrontabSchedule.Parse(item.Cron, new CrontabSchedule.ParseOptions
{
2024-12-11 22:02:22 +00:00
IncludingSeconds = false // Ensure you account for seconds
2024-12-10 21:16:03 +00:00
});
2024-12-03 22:52:14 +00:00
2024-12-10 21:16:03 +00:00
// Get the current time
var currentTime = DateTime.UtcNow;
2024-12-03 22:52:14 +00:00
2024-12-10 21:16:03 +00:00
// Get the next occurrence from the schedule
var nextOccurrence = schedule.GetNextOccurrence(currentTime.AddSeconds(-1));
2024-12-03 22:52:14 +00:00
2024-12-10 21:16:03 +00:00
// Check if the current time matches the schedule
bool matches = currentTime >= nextOccurrence && currentTime < nextOccurrence.AddSeconds(1);
2024-12-03 22:52:14 +00:00
2024-12-10 21:16:03 +00:00
if (matches)
{
_logger.LogDebug($"The current time matches the cron expression {item}");
cron.ScheduledTimeArrived(item);
}
}
catch (Exception ex)
2024-12-03 22:52:14 +00:00
{
2024-12-10 21:16:03 +00:00
_logger.LogWarning($"Error when running cron task ({item.ConversationId}, {item.Title}, {item.Cron}): {ex.Message}\r\n{ex.InnerException}");
continue;
2024-12-03 22:52:14 +00:00
}
}
}
}