diff --git a/src/SIL.Machine.AspNetCore/Configuration/IMachineBuilderExtensions.cs b/src/SIL.Machine.AspNetCore/Configuration/IMachineBuilderExtensions.cs index 8755aa7b4..6089d64a9 100644 --- a/src/SIL.Machine.AspNetCore/Configuration/IMachineBuilderExtensions.cs +++ b/src/SIL.Machine.AspNetCore/Configuration/IMachineBuilderExtensions.cs @@ -405,29 +405,10 @@ public static IMachineBuilder AddBuildJobService(this IMachineBuilder builder) return builder; } - public static IMachineBuilder AddModelCleanupJob(this IMachineBuilder builder, string? connectionString = null) + public static IMachineBuilder AddModelCleanupService(this IMachineBuilder builder) { - connectionString ??= builder.Configuration?.GetConnectionString("Hangfire"); - if (connectionString is null) - throw new InvalidOperationException("Hangfire connection string is required"); - - var mongoUrl = MongoUrl.Create(connectionString); - JobStorage.Current = new MongoStorage( - MongoClientSettings.FromUrl(mongoUrl), - mongoUrl.DatabaseName, - GetMongoStorageOptions() - ); - builder.Services.AddSingleton(); - RecurringJob.AddOrUpdate( - recurringJobId: "cleanup-job", - queue: "cleanup-job", - methodCall: o => o.RunAsync(), - cronExpression: Cron.Minutely - ); - builder.Services.AddHangfireServer(o => - { - o.Queues = ["cleanup-job"]; - }); + builder.Services.AddSingleton(); + builder.Services.AddHostedService(p => p.GetRequiredService()); return builder; } diff --git a/src/SIL.Machine.AspNetCore/Services/CleanupJob.cs b/src/SIL.Machine.AspNetCore/Services/CleanupOldModelsService.cs similarity index 85% rename from src/SIL.Machine.AspNetCore/Services/CleanupJob.cs rename to src/SIL.Machine.AspNetCore/Services/CleanupOldModelsService.cs index c42833f02..2e302b880 100644 --- a/src/SIL.Machine.AspNetCore/Services/CleanupJob.cs +++ b/src/SIL.Machine.AspNetCore/Services/CleanupOldModelsService.cs @@ -1,25 +1,27 @@ namespace SIL.Machine.AspNetCore.Services; -public class CleanupOldModelsJob( +public class CleanupOldModelsService( + IServiceProvider services, ISharedFileService sharedFileService, IRepository engines, - ILogger logger -) : ICleanupOldModelsJob + ILogger logger +) : RecurrentTask("Cleanup Old Models Service", services, RefreshPeriod, logger) { public ISharedFileService SharedFileService { get; } = sharedFileService; - private ILogger _logger = logger; + private ILogger _logger = logger; private IRepository _engines = engines; private List _filesPreviouslyMarkedForDeletion = []; private readonly List _filesNewlyMarkedForDeletion = []; + private static readonly TimeSpan RefreshPeriod = TimeSpan.FromDays(1); - public async Task RunAsync() + protected override async Task DoWorkAsync(IServiceScope scope, CancellationToken cancellationToken) { await CheckModelsAsync(); } public async Task CheckModelsAsync() { - _logger.LogDebug("Running model cleanup job"); + _logger.LogInformation("Running model cleanup job"); var paths = await SharedFileService.ListFilesAsync(ISharedFileService.ModelDirectory); foreach (string path in paths) { diff --git a/src/SIL.Machine.AspNetCore/Services/ICleanupJob.cs b/src/SIL.Machine.AspNetCore/Services/ICleanupJob.cs deleted file mode 100644 index c51c59503..000000000 --- a/src/SIL.Machine.AspNetCore/Services/ICleanupJob.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace SIL.Machine.AspNetCore.Services; - -public interface ICleanupOldModelsJob -{ - public Task RunAsync(); -} diff --git a/src/SIL.Machine.Serval.EngineServer/Program.cs b/src/SIL.Machine.Serval.EngineServer/Program.cs index c661f1393..5140b15a3 100644 --- a/src/SIL.Machine.Serval.EngineServer/Program.cs +++ b/src/SIL.Machine.Serval.EngineServer/Program.cs @@ -1,5 +1,6 @@ using Hangfire; using OpenTelemetry.Trace; +using SIL.Machine.AspNetCore.Services; var builder = WebApplication.CreateBuilder(args); @@ -10,7 +11,7 @@ .AddMongoHangfireJobClient() .AddServalTranslationEngineService() .AddBuildJobService() - .AddModelCleanupJob() + .AddModelCleanupService() .AddClearMLService(); if (builder.Environment.IsDevelopment()) diff --git a/tests/SIL.Machine.AspNetCore.Tests/Services/CleanupJobTests.cs b/tests/SIL.Machine.AspNetCore.Tests/Services/CleanupJobTests.cs index 3f87e5c1e..0db8163a1 100644 --- a/tests/SIL.Machine.AspNetCore.Tests/Services/CleanupJobTests.cs +++ b/tests/SIL.Machine.AspNetCore.Tests/Services/CleanupJobTests.cs @@ -57,21 +57,22 @@ async Task WriteFileStub(string path, string content) } [Test] - public async Task RunAsync_ValidFiles() + public async Task DoWorkAsync_ValidFiles() { await SetUpAsync(); - var cleanupJob = new CleanupOldModelsJob( + var cleanupJob = new CleanupOldModelsService( + Substitute.For(), _sharedFileService, _engines, - Substitute.For>() + Substitute.For>() ); - await cleanupJob.RunAsync(); + await cleanupJob.CheckModelsAsync(); // both valid and invalid files still exist after running once Assert.That( _sharedFileService.ListFilesAsync("models").Result.ToHashSet(), Is.EquivalentTo(validFiles.Concat(invalidFiles).ToHashSet()) ); - await cleanupJob.RunAsync(); + await cleanupJob.CheckModelsAsync(); // only valid files exist after running twice Assert.That( _sharedFileService.ListFilesAsync("models").Result.ToHashSet(),