Using version 1.8.14 here. I have a job that is a long-running job. I’m utilizing cancellation tokens to gracefully clean things up. However, I’m not quite understanding how to handle these two situations:
-
My app has a stop button. This button calls BackgroundJob.Delete. This triggers the cancellation token and my job has the chance to clean things up. And the job gets put in Deleted status. I think this is working as I’d expect.
-
There is a Windows service that runs BackgroundJobServer. When this service shuts down, the BackgroundJobServer gets disposed. That also triggers the cancellation token and the job has a chance for cleanup which I’d expect. Unfortunately, the job is then getting put in Succeeded status. This is something I’m not understanding, especially given this:
Hangfire provides support for cancellation tokens for our background jobs to let them know
when a shutdown request was initiated, or job performance was aborted. In the former case the
job will be automatically put back to the beginning of its queue, allowing Hangfire to process it
after restart.
What am I missing here?
If it helps, here is the Windows service code:
public sealed class WindowsBackgroundService(
IServiceProvider serviceProvider,
ILogger<WindowsBackgroundService> logger) : BackgroundService
{
private ILogger<WindowsBackgroundService> Logger
{
get;
} = logger;
private IServiceProvider ServiceProvider
{
get;
} = serviceProvider;
protected override async Task ExecuteAsync(
CancellationToken stoppingToken)
{
try
{
await ServiceProvider.GetRequiredService<IHangfireProcessor>()
.RunAsync(stoppingToken);
}
catch (Exception ex)
{
Logger.LogError(ex, "{Message}", ex.Message);
Environment.Exit(1);
}
}
}
And here is where the BackgroundJobServer gets executed:
public class HangfireProcessor(
ILogger<HangfireProcessor> logger) : IHangfireProcessor
{
private ILogger<HangfireProcessor> Logger
{
get;
} = logger;
public async Task RunAsync(CancellationToken token)
{
var options = new BackgroundJobServerOptions
{
ServerTimeout = TimeSpan.FromHours(24)
};
try
{
using var server = new BackgroundJobServer(options);
Logger.LogInformation("Hangfire server started.");
while (!token.IsCancellationRequested)
{
await Task.Delay(1000, token);
}
}
catch (OperationCanceledException)
{
Logger.LogWarning("Hangfire shutdown requested.");
}
catch (Exception ex)
{
Logger.LogError("Serious error occurred with Hangfire server.");
Logger.LogError(ex, ex.Message);
}
finally
{
Logger.LogWarning("Hangfire server stopped.");
}
}
}
Also to clarify, this is .NET Core.