feat: scaffolding for background tasks complete

This commit is contained in:
Michael Green
2023-03-17 23:08:46 +11:00
parent 55735599f8
commit 5260738a5b
9 changed files with 397 additions and 35 deletions

View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace gaseous_server.Controllers
{
[ApiController]
[Route("api/v1/[controller]")]
public class BackgroundTasksController : Controller
{
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
public List<ProcessQueue.QueueItem> GetQueue()
{
return ProcessQueue.QueueItems;
}
[HttpGet]
[Route("{TaskType}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<ProcessQueue.QueueItem> ForceRun(ProcessQueue.QueueItemType TaskType, Boolean ForceRun)
{
foreach (ProcessQueue.QueueItem qi in ProcessQueue.QueueItems)
{
if (TaskType == qi.ItemType)
{
if (ForceRun == true)
{
qi.ForceExecute();
}
return qi;
}
}
return NotFound();
}
}
}

View File

@@ -20,13 +20,14 @@ namespace gaseous_server.Controllers
/// </summary>
/// <returns>Number of sources, publishers, games, and rom signatures in the database</returns>
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
public Models.Signatures_Status Status()
{
return new Models.Signatures_Status();
}
[HttpGet]
[Route("api/[controller]/[action]")]
[ProducesResponseType(StatusCodes.Status200OK)]
public List<Models.Signatures_Games> GetSignature(string md5 = "", string sha1 = "")
{
if (md5.Length > 0)

View File

@@ -0,0 +1,107 @@
using System;
using gaseous_tools;
namespace gaseous_server
{
public static class ProcessQueue
{
public static List<QueueItem> QueueItems = new List<QueueItem>();
public class QueueItem
{
public QueueItem(QueueItemType ItemType, int ExecutionInterval)
{
_ItemType = ItemType;
_ItemState = QueueItemState.NeverStarted;
_LastRunTime = DateTime.UtcNow.AddMinutes(ExecutionInterval);
_Interval = ExecutionInterval;
}
private QueueItemType _ItemType = QueueItemType.NotConfigured;
private QueueItemState _ItemState = QueueItemState.NeverStarted;
private DateTime _LastRunTime = DateTime.UtcNow;
private DateTime _LastFinishTime = DateTime.UtcNow;
private int _Interval = 0;
private string _LastResult = "";
private Exception? _LastError = null;
private bool _ForceExecute = false;
public QueueItemType ItemType => _ItemType;
public QueueItemState ItemState => _ItemState;
public DateTime LastRunTime => _LastRunTime;
public DateTime LastFinishTime => _LastFinishTime;
public DateTime NextRunTime {
get
{
return LastRunTime.AddMinutes(Interval);
}
}
public int Interval => _Interval;
public string LastResult => _LastResult;
public Exception? LastError => _LastError;
public bool Force => _ForceExecute;
public void Execute()
{
if (_ItemState != QueueItemState.Disabled)
{
if ((DateTime.UtcNow > NextRunTime || _ForceExecute == true) && _ItemState != QueueItemState.Running)
{
// we can run - do some setup before we start processing
_LastRunTime = DateTime.UtcNow;
_ItemState = QueueItemState.Running;
_LastResult = "";
_LastError = null;
_ForceExecute = false;
Logging.Log(Logging.LogType.Information, "Timered Event", "Executing " + _ItemType);
try
{
switch (_ItemType)
{
case QueueItemType.SignatureIngestor:
Logging.Log(Logging.LogType.Information, "Timered Event", "Starting Signature Ingestor");
break;
case QueueItemType.TitleIngestor:
Logging.Log(Logging.LogType.Information, "Timered Event", "Starting Title Ingestor");
break;
}
}
catch (Exception ex)
{
Logging.Log(Logging.LogType.Warning, "Timered Event", "An error occurred", ex);
_LastResult = "";
_LastError = ex;
}
_ItemState = QueueItemState.Stopped;
_LastFinishTime = DateTime.UtcNow;
}
}
}
public void ForceExecute()
{
_ForceExecute = true;
}
}
public enum QueueItemType
{
NotConfigured,
SignatureIngestor,
TitleIngestor
}
public enum QueueItemState
{
NeverStarted,
Running,
Stopped,
Disabled
}
}
}

View File

@@ -2,20 +2,31 @@
using gaseous_server;
using gaseous_tools;
Logging.Log(Logging.LogType.Information, "Startup", "Starting Gaseous Server");
// set up db
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
db.InitDB();
// set initial values
Guid APIKey = Guid.NewGuid();
if (Config.ReadSetting("API Key", "Test API Key") == "Test API Key")
{
// it's a new api key save it
Logging.Log(Logging.LogType.Information, "Startup", "Setting initial API key");
Config.SetSetting("API Key", APIKey.ToString());
}
// set up server
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers().AddJsonOptions(x =>
{
// serialize enums as strings in api responses (e.g. Role)
x.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
@@ -36,6 +47,9 @@ app.UseAuthorization();
app.MapControllers();
// add background tasks
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(ProcessQueue.QueueItemType.SignatureIngestor, 60));
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(ProcessQueue.QueueItemType.TitleIngestor, 1));
// start the app
app.Run();

View File

@@ -1,4 +1,5 @@
using System;
using gaseous_tools;
namespace gaseous_server
{
@@ -6,17 +7,18 @@ namespace gaseous_server
public class TimedHostedService : IHostedService, IDisposable
{
private int executionCount = 0;
private readonly ILogger<TimedHostedService> _logger;
//private readonly ILogger<TimedHostedService> _logger;
private Timer _timer;
public TimedHostedService(ILogger<TimedHostedService> logger)
{
_logger = logger;
}
//public TimedHostedService(ILogger<TimedHostedService> logger)
//{
// _logger = logger;
//}
public Task StartAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Timed Hosted Service running.");
//_logger.LogInformation("Timed Hosted Service running.");
Logging.Log(Logging.LogType.Debug, "Background", "Starting background task monitor");
_timer = new Timer(DoWork, null, TimeSpan.Zero,
TimeSpan.FromSeconds(5));
@@ -28,13 +30,20 @@ namespace gaseous_server
{
var count = Interlocked.Increment(ref executionCount);
_logger.LogInformation(
"Timed Hosted Service is working. Count: {Count}", count);
//_logger.LogInformation(
// "Timed Hosted Service is working. Count: {Count}", count);
foreach (ProcessQueue.QueueItem qi in ProcessQueue.QueueItems) {
if (DateTime.UtcNow > qi.NextRunTime || qi.Force == true) {
qi.Execute();
}
}
}
public Task StopAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Timed Hosted Service is stopping.");
//_logger.LogInformation("Timed Hosted Service is stopping.");
Logging.Log(Logging.LogType.Debug, "Background", "Stopping background task monitor");
_timer?.Change(Timeout.Infinite, 0);

View File

@@ -10,8 +10,9 @@
<PropertyGroup Condition=" '$(RunConfiguration)' == 'https' " />
<PropertyGroup Condition=" '$(RunConfiguration)' == 'http' " />
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.3" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.4" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="7.0.5" />
</ItemGroup>
<ItemGroup>
@@ -21,6 +22,9 @@
<ProjectReference Include="..\gaseous-romsignatureobject\gaseous-romsignatureobject.csproj">
<GlobalPropertiesToRemove></GlobalPropertiesToRemove>
</ProjectReference>
<ProjectReference Include="..\gaseous-signature-ingestor\gaseous-signature-ingestor.csproj">
<GlobalPropertiesToRemove></GlobalPropertiesToRemove>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Remove="Controllers\" />