using Extrudex.Domain.Interfaces; using Extrudex.Infrastructure.Configuration; 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 IMoonrakerPrinterSyncService _syncService; private readonly MoonrakerPrinterSyncOptions _options; private readonly ILogger _logger; /// /// Creates a new MoonrakerPrinterSyncJob. /// /// The service that performs the actual sync logic. /// Configuration options for polling interval and timeouts. /// Logger for diagnostic output. public MoonrakerPrinterSyncJob( IMoonrakerPrinterSyncService syncService, IOptions options, ILogger logger) { _syncService = syncService; _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 { 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"); } }