Reputation: 1
We are using Hangfire version 1.7.36. I'm trying to set the JobExpirationTimeout from the OnStateApplied() method to retain succeeded and deleted jobs just for 7 hours. I have set the timeout globally using WithJobExpirationTimeout(). We have an existing attribute that sets the timeout, so I'm changing the maximum timeout to 7 hours if the value passed in exceeds that. This logic works fine for deleted job, but succeeded jobs either still show the time passed in as argument when using the time out attribute or 24 hours for methods not using the attribute. I'm stuck and don't know what else to do. Note: while debugging, the JobExpirationTimeout property did set, but it comes out different on the dashboard. Also note that breakpoint is not getting hit in the OnStateApplied() method when a job succeeds.
I have set the timeout globally using WithJobExpirationTimeout(). We have an existing attribute that sets the timeout, so I'm changing the maximum timeout to 7 hours if the value passed in exceeds that. This logic works fine for deleted job, but succeeded jobs either still show the time passed in as argument when using the time out attribute or 24 hours for methods not using the attribute.
Upvotes: 0
Views: 58
Reputation: 8936
Your demand filter/attribute should be like this:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class CustomExpirationFilter : JobFilterAttribute, IApplyStateFilter
{
private readonly TimeSpan _expirationTimeout;
public CustomExpirationFilter(int hours)
{
_expirationTimeout = TimeSpan.FromHours(hours);
}
public void OnStateApplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
{
if (context.NewState is SucceededState || context.NewState is DeletedState)
{
context.JobExpirationTimeout = _expirationTimeout;
}
}
public void OnStateUnapplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
{
// Optional: logic when state is unapplied
}
}
If you set it as a global "filter" to apply to all jobs you could see OnStateApplied is called.
If you want to use as "attribute" you need to apply it to the job method.
[HttpPost("fire")]
public IActionResult FireAndForgetJob()
{
_backgroundJobClient.Enqueue(() => ExecuteJobWithCustomExpirationFilter());
return Ok("Fire job queued.");
}
[CustomExpirationFilter(3)] // Attribute-based expiration of 3 hours
public Task ExecuteJobWithCustomExpirationFilter()
{
Console.WriteLine("Executing job with attribute-based expiration.");
return Task.CompletedTask; // Returning a completed task for synchronous code
}
Upvotes: 0