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;
using System.Threading.Tasks; using System.Threading.Tasks;
using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Logging; using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Types.Logging; using LBPUnion.ProjectLighthouse.Types.Logging;
using LBPUnion.ProjectLighthouse.Types.Maintenance; using LBPUnion.ProjectLighthouse.Types.Maintenance;
@ -47,35 +48,40 @@ public class RepeatingTaskService : BackgroundService
await Task.Yield(); await Task.Yield();
while (!stoppingToken.IsCancellationRequested) 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 if (!this.TryGetNextTask(out IRepeatingTask? task) || task == null)
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 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); await Task.Delay(timeToWait, stoppingToken);
} }
catch (TaskCanceledException)
{
break;
}
}
using IServiceScope scope = this.provider.CreateScope(); using IServiceScope scope = this.provider.CreateScope();
DatabaseContext database = scope.ServiceProvider.GetRequiredService<DatabaseContext>(); DatabaseContext database = scope.ServiceProvider.GetRequiredService<DatabaseContext>();
await task.Run(database); // Set LastRan before running so if an exception occurs, the task doesn't immediately try to run again
Logger.Debug($"Successfully ran task \"{task.Name}\"", LogArea.Maintenance); task.LastRan = DateTime.UtcNow;
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);
}
} }
} }
} }