In my custom JobFilterAttribute, i am implementing IElectStateFilter. I am trying to delete any duplicate jobs with that method name that are already running. In effect, I only want one instance of the job running at a time.
I would like to handle this without having to have a single worker server
Using MSMQ and SqlServer and Hangfire 1.4.1.
When a job is queued to run, i store the current jobId to my Tasks table
if (context.CandidateState is EnqueuedState)
{
var e = (EnqueuedState)context.CandidateState;
if (e.Reason != null && e.Reason.Contains("scheduler"))
{
task.RunningJobId = context.JobId;
task.CurrentStatus = (byte)ScheduledTaskStatus.Queued;
_repo.Save(task, ref tran);
}
}
When a Task is triggered manually, I also store the JobId in the database (either using this same code using RecurringJob.Trigger(code) or BackgroundJob.Enqueue().
So in the case where the user manually runs a task and while it is still either enqueued or processing, the scheduler triggers it to run, I want to delete that scheduler triggered execution of the Task:
public void OnStateElection(ElectStateContext context)
{
var task = GetTask(context.JobId, ref tran); // get the Task from the database
if (!(string.IsNullOrEmpty(task.RunningJobId)) && task.RunningJobId != context.JobId) //do not allow multiple jobs to run for the same scheduled task
{
BackgroundJob.Delete(context.JobId);
}
else
{
// status update code
}
}
When I try to delete the job, I get a SQL timeout with the blocking statement being:
(@id nvarchar(4000))select InvocationData, StateName, Arguments, CreatedAt from HangFire.Job where Id = @id
I’m not sure if there’s some sort of transactional lock on the OnStateElection method or what is happening.
If you have any suggestions for how to handle this or how i can delete the job, please let me know.