Disable re-queueing of failed Hangfire BackgroundJob
Asked Answered
W

5

53

Is there a way to disable re-queueing of a failed Hangfire BackgroundJob?

We do not want the failed jobs to be executed again as this might cause issues.

Wellordered answered 4/3, 2015 at 8:10 Comment(0)
W
47

Solved, using [AutomaticRetry(Attempts = 0)]

Wellordered answered 4/3, 2015 at 8:44 Comment(3)
You may also add OnAttemptsExceeded = AttemptsExceededAction.Delete to ignore them and do not blow up the "failed jobs" page.Unproductive
This solution is what that docs say to do, but in practice, I don't see a difference in the running system. My failed jobs retry themselves even when this attribute is on the method that I'm calling from my recurring Job. Others seem to have the same problem too.Formula
if using DI container you must put the attribute on the interface definition and not on the implementation. eg. interface IMyService { [AutomaticRetry(Attempts = 0)void MyMethod(); }Moluccas
M
31

You can either annotate the method to run in the background with the following attribute:

[AutomaticRetry(Attempts = 0)]

Or set it globally:

GlobalJobFilters.Filters.Add(new AutomaticRetryAttribute { Attempts = 0 });
Mascara answered 11/5, 2018 at 15:10 Comment(1)
But how do you do this on a job-by-job basis? Say you want retries by defualy, but a job failed in an unrecoverable way and you don't want it to retry that specific job.Domenicadomenico
M
20

Important if using DI container with an interface, you must put the attribute on the interface definition

public interface IDataUpdater
{
    [Hangfire.AutomaticRetry(Attempts = 0, OnAttemptsExceeded = AttemptsExceededAction.Delete)]
    void UpdateData();
}

Queue the job like this

Hangfire.RecurringJob.AddOrUpdate<IDataUpdater>(updater => updater.UpdateData(), Cron.Hourly);

Test it by just throwing any old exception within your implementation. If you've done it right you'll see this in the job history under 'deleted'.

enter image description here

Moluccas answered 8/5, 2018 at 1:45 Comment(0)
C
9

Ran into this today but wanted to set the Retry Filter globally in a .NET API application.

The following worked...

services.AddHangfire(configuration => {
            // Disable retry for failed jobs
            // https://docs.hangfire.io/en/latest/background-processing/dealing-with-exceptions.html?highlight=retry
            configuration.UseFilter(new AutomaticRetryAttribute { Attempts = 0 });
        });
Corneliacornelian answered 18/1, 2021 at 19:42 Comment(0)
C
7

I ran into a similar issue and I was able to find a solution. Using a global filter was not an option for me. I'm using asp.net core and I have a simple fire and forget background job. For some reason the AutomaticRetryAttribute was being ignored. It turned out the way I was adding the job was the key to my solution. I had a similar code in my app that was causing the issue:

BackgroundJob.Enqueue<IMyJobService>(js => js.DoWork());

In my IMyJobService implementation I had the following code:

[AutomaticRetry(Attempts = 0)]
public void DoWork()
{
    // I'm working hard here
}

The solution that I came up with was:

public MyTestController
{
    private readonly IMyJobService _myJobService;

    public MyTestClass(IMyJobService myJobService)
    {
        _myJobService = myJobService;
    }

    public ActionResult Work()
    {
        BackgroundJob.Enqueue(() => _myJobService.DoWork());
        return Ok();
    }
}

Instead of relying on BackgroundJob.Enqueue<T> to inject my IMyJobService implementation I do it myself. That's basically it. I hope this will help someone.

Coarse answered 24/8, 2017 at 10:58 Comment(1)
I solved the same issue putting the AutomaticRetryAttribute on the method definition of the interface, not on the implemented one.Unbolted

© 2022 - 2024 — McMap. All rights reserved.