using Extrudex.Domain.Interfaces;
using Extrudex.Infrastructure.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Extrudex.API.Jobs;
///
/// Background service that periodically syncs Moonraker printer status
/// and print job history into the Extrudex database. Runs as a hosted
/// service and polls all active Moonraker printers on a configurable
/// interval to update printer state and map completed print jobs
/// to PrintJob and FilamentUsage entities.
///
/// Configuration is bound from the "MoonrakerPrinterSync" section in
/// appsettings.json. Set Enabled=false to disable without removing
/// the service registration.
///
public class MoonrakerPrinterSyncJob : BackgroundService
{
private readonly IServiceScopeFactory _scopeFactory;
private readonly MoonrakerPrinterSyncOptions _options;
private readonly ILogger _logger;
///
/// Creates a new MoonrakerPrinterSyncJob.
///
/// Factory for creating DI scopes to resolve scoped services.
/// Configuration options for polling interval and timeouts.
/// Logger for diagnostic output.
public MoonrakerPrinterSyncJob(
IServiceScopeFactory scopeFactory,
IOptions options,
ILogger logger)
{
_scopeFactory = scopeFactory;
_options = options.Value;
_logger = logger;
}
///
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
if (!_options.Enabled)
{
_logger.LogInformation("Moonraker printer sync job is disabled via configuration — exiting");
return;
}
_logger.LogInformation(
"Moonraker printer sync job starting — polling every {Interval}",
_options.PollingInterval);
// Delay briefly on startup to allow the web host to fully initialize
await Task.Delay(TimeSpan.FromSeconds(15), stoppingToken);
while (!stoppingToken.IsCancellationRequested)
{
try
{
using var scope = _scopeFactory.CreateScope();
var syncService = scope.ServiceProvider.GetRequiredService();
var syncedCount = await syncService.SyncAllAsync(stoppingToken);
_logger.LogInformation(
"Moonraker printer sync completed — {SyncedCount} printer(s) synced. Next sync in {Interval}",
syncedCount, _options.PollingInterval);
}
catch (Exception ex) when (ex is not OperationCanceledException)
{
_logger.LogError(ex,
"Error during Moonraker printer sync cycle — will retry in {Interval}",
_options.PollingInterval);
}
await Task.Delay(_options.PollingInterval, stoppingToken);
}
_logger.LogInformation("Moonraker printer sync job shutting down");
}
}