namespace OpenNest.Server.Worker;
///
/// Runs until the host stops: straight on to the next job after
/// one finishes, otherwise every . Touches
/// each round and on each heartbeat of a running job;
/// the container health check reads it.
///
public sealed class NestJobWorkerService : BackgroundService
{
private readonly NestJobWorker _worker;
private readonly WorkerOptions _options;
private readonly ILogger _logger;
public NestJobWorkerService(NestJobWorker worker, WorkerOptions options, ILogger logger)
{
_worker = worker;
_options = options;
_logger = logger;
_worker.Alive = Touch;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Nest worker {Id} polling {Server}.", _worker.WorkerId, _options.ServerUrl);
while (!stoppingToken.IsCancellationRequested)
{
Touch();
var ran = false;
try
{
ran = await _worker.RunOnceAsync(stoppingToken);
}
catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
{
return;
}
catch (Exception ex) when (ex is IOException or HttpRequestException or TaskCanceledException)
{
_logger.LogWarning("Nest server unavailable: {Message}", ex.Message);
}
if (ran)
continue;
try { await Task.Delay(_options.PollInterval, stoppingToken); }
catch (OperationCanceledException) { return; }
}
}
private void Touch()
{
try { File.WriteAllText(_options.AliveFile, DateTime.UtcNow.ToString("o")); }
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException) { }
}
}