Handle exceptions in repeating tasks

This commit is contained in:
Slendy 2023-06-18 15:59:32 -05:00
commit 8b1121a4f8
No known key found for this signature in database
GPG key ID: 7288D68361B91428

View file

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Types.Logging;
using LBPUnion.ProjectLighthouse.Types.Maintenance;
@ -47,35 +48,40 @@ public class RepeatingTaskService : BackgroundService
await Task.Yield();
while (!stoppingToken.IsCancellationRequested)
{
if (!this.TryGetNextTask(out IRepeatingTask? task) || task == null)
try
{
// If we fail to fetch the next task then something has gone wrong and the service should halt
Logger.Debug("Failed to fetch next smallest task", LogArea.Maintenance);
return;
}
TimeSpan timeElapsedSinceRun = DateTime.UtcNow.Subtract(task.LastRan);
// If the task's repeat interval hasn't elapsed
if (timeElapsedSinceRun < task.RepeatInterval)
{
TimeSpan timeToWait = task.RepeatInterval.Subtract(timeElapsedSinceRun);
Logger.Debug($"Waiting {timeToWait} for {task.Name}", LogArea.Maintenance);
try
if (!this.TryGetNextTask(out IRepeatingTask? task) || task == null)
{
// If we fail to fetch the next task then something has gone wrong and the service should halt
Logger.Debug("Failed to fetch next smallest task", LogArea.Maintenance);
return;
}
TimeSpan timeElapsedSinceRun = DateTime.UtcNow.Subtract(task.LastRan);
// If the task's repeat interval hasn't elapsed
if (timeElapsedSinceRun < task.RepeatInterval)
{
TimeSpan timeToWait = task.RepeatInterval.Subtract(timeElapsedSinceRun);
Logger.Debug($"Waiting {timeToWait} for {task.Name}", LogArea.Maintenance);
await Task.Delay(timeToWait, stoppingToken);
}
catch (TaskCanceledException)
{
break;
}
}
using IServiceScope scope = this.provider.CreateScope();
DatabaseContext database = scope.ServiceProvider.GetRequiredService<DatabaseContext>();
await task.Run(database);
Logger.Debug($"Successfully ran task \"{task.Name}\"", LogArea.Maintenance);
task.LastRan = DateTime.UtcNow;
using IServiceScope scope = this.provider.CreateScope();
DatabaseContext database = scope.ServiceProvider.GetRequiredService<DatabaseContext>();
// Set LastRan before running so if an exception occurs, the task doesn't immediately try to run again
task.LastRan = DateTime.UtcNow;
await task.Run(database);
Logger.Debug($"Successfully ran task \"{task.Name}\"", LogArea.Maintenance);
}
catch (TaskCanceledException)
{
break;
}
catch (Exception e)
{
Logger.Error($"Error while running repeating task: {e.ToDetailedException()}", LogArea.Maintenance);
}
}
}
}