Add system for repeating tasks on a regular basis

This commit is contained in:
jvyden 2022-08-05 19:27:37 -04:00
parent 39c969f3a9
commit 688c0ae4c2
No known key found for this signature in database
GPG key ID: 18BCF2BE0262B278
8 changed files with 110 additions and 23 deletions

View file

@ -0,0 +1,13 @@
using System;
using System.Threading.Tasks;
namespace LBPUnion.ProjectLighthouse.Administration.Maintenance;
public interface IRepeatingTask
{
public string Name { get; }
public TimeSpan RepeatInterval { get; }
public DateTime LastRan { get; set; }
public Task Run(Database database);
}

View file

@ -2,8 +2,10 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Logging;
@ -18,11 +20,13 @@ public static class MaintenanceHelper
Commands = getListOfInterfaceObjects<ICommand>();
MaintenanceJobs = getListOfInterfaceObjects<IMaintenanceJob>();
MigrationTasks = getListOfInterfaceObjects<IMigrationTask>();
RepeatingTasks = getListOfInterfaceObjects<IRepeatingTask>();
}
public static List<ICommand> Commands { get; }
public static List<IMaintenanceJob> MaintenanceJobs { get; }
public static List<IMigrationTask> MigrationTasks { get; }
public static List<IRepeatingTask> RepeatingTasks { get; }
public static async Task<List<LogLine>> RunCommand(string[] args)
{

View file

@ -0,0 +1,13 @@
using System;
using System.Threading.Tasks;
using LBPUnion.ProjectLighthouse.Match.Rooms;
namespace LBPUnion.ProjectLighthouse.Administration.Maintenance.RepeatingTasks;
public class CleanupRoomsTask : IRepeatingTask
{
public string Name => "Cleanup Rooms";
public TimeSpan RepeatInterval => TimeSpan.FromSeconds(10);
public DateTime LastRan { get; set; }
public async Task Run(Database database) => RoomHelper.CleanupRooms();
}

View file

@ -0,0 +1,13 @@
using System;
using System.Threading.Tasks;
namespace LBPUnion.ProjectLighthouse.Administration.Maintenance.RepeatingTasks;
public class RemoveExpiredTokensTask : IRepeatingTask
{
public string Name => "Remove Expired Tokens";
public TimeSpan RepeatInterval => TimeSpan.FromHours(1);
public DateTime LastRan { get; set; }
public Task Run(Database database) => database.RemoveExpiredTokens();
}

View file

@ -0,0 +1,62 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using LBPUnion.ProjectLighthouse.Administration.Maintenance;
using LBPUnion.ProjectLighthouse.Logging;
namespace LBPUnion.ProjectLighthouse.Administration;
public static class RepeatingTaskHandler
{
private static bool initialized = false;
public static void Initialize()
{
if (initialized) throw new InvalidOperationException("RepeatingTaskHandler was initialized twice");
initialized = true;
Task.Factory.StartNew(taskLoop);
}
[SuppressMessage("ReSharper", "FunctionNeverReturns")]
private static async Task taskLoop()
{
Queue<IRepeatingTask> taskQueue = new();
foreach (IRepeatingTask task in MaintenanceHelper.RepeatingTasks) taskQueue.Enqueue(task);
Database database = new();
while (true)
{
try
{
if (!taskQueue.TryDequeue(out IRepeatingTask? task))
{
Thread.Sleep(100);
continue;
}
Debug.Assert(task != null);
if ((task.LastRan + task.RepeatInterval) <= DateTime.Now)
{
await task.Run(database);
task.LastRan = DateTime.Now;
Logger.Debug($"Ran task \"{task.Name}\"", LogArea.Maintenace);
}
taskQueue.Enqueue(task);
Thread.Sleep(500); // Doesn't need to be that precise.
}
catch
{
// ignored
}
}
}
}

View file

@ -22,4 +22,5 @@ public enum LogArea
Command,
Admin,
Publish,
Maintenace,
}

View file

@ -21,22 +21,6 @@ public class RoomHelper
public static readonly object RoomLock = new();
public static StorableList<Room> Rooms => RoomStore.GetRooms();
public static void StartCleanupThread()
{
// ReSharper disable once FunctionNeverReturns
Task.Factory.StartNew
(
async () =>
{
while (true)
{
CleanupRooms();
await Task.Delay(10000);
}
}
);
}
private static int roomIdIncrement;
internal static int RoomIdIncrement => roomIdIncrement++;

View file

@ -89,14 +89,11 @@ public static class StartupTasks
Logger.Info("Initializing Redis...", LogArea.Startup);
RedisDatabase.Initialize().Wait();
Logger.Info("Initializing repeating tasks...", LogArea.Startup);
RepeatingTaskHandler.Initialize();
if (serverType == ServerType.GameServer)
{
Logger.Info("Starting room cleanup thread...", LogArea.Startup);
RoomHelper.StartCleanupThread();
}
// Create admin user if no users exist
// Create admin user if no users exist
if (serverType == ServerType.Website && database.Users.CountAsync().Result == 0)
{
const string passwordClear = "lighthouse";