How to run only one job concurrently?
Asked Answered
B

2

10

I have one hangfire server with ~50 recurring jobs. Hangfire setting up on IIS like in this example. Recurring jobs added to hangfire in startup.cs like this:

RecurringJob.AddOrUpdate(job.desctiprion,
            () => job.startJob(), 
            job.cron, 
            TimeZoneInfo.Local);

I need to add new recurring job which running every minute. But there is little chance that this job will be running longer minute. My goal - provide to concurrently work only one exemplar of this job.

What solutions are there? As I understand need something like queue with one thread, but queues don't support thread settings.

Boarish answered 20/7, 2016 at 14:41 Comment(3)
It's not clear what you're trying to do, 'only one' and 'concurrently' don't really seem to go together. This: provide to concurrently work only one exemplar of this job doesn't make any sense. Can you clarify?Verenaverene
So you just want to ensure that this job doesn't overlap with itself?Brenner
I need avoid situation when at one moment more than one instance of this recurring job in processing. Yes I just want to ensure that this job doesn't overlap with itself. For example: first job run in 17:00 and this run take 2 minutes 30 seconds. I need avoid job run in 17:01 and 17:02 but run job in 17:03. I understand that I can use any flag in the database for verification whether the job is now running . But perhaps in Hangfire has a simple and correct solution to this case.Boarish
T
17

You can use DisableConcurrentExecution filter to prevent concurrent executions.

[DisableConcurrentExecution(timeoutInSeconds: 60)]
public void SomeJob()
{
  //method body
}

This filter places a distributed lock in the beginning of a method performance and releases it after it was completed using the IServerFilter interface. The type and method name are being used as a locking resource. Each storage uses its own distributed lock implementation. (read more here)

Thunderhead answered 22/7, 2016 at 5:5 Comment(1)
Thanks, you answer is very helpfull. Can also be used [AutomaticRetry(Attempts = 0)] for avoid large jobs count in retry.Boarish
M
-5
 var worker = new BackgroundWorker();
 worker.DoWork += worker_DoWork;
 worker.RunWorkerCompleted += worker_RunWorkerCompleted;
 private void worker_DoWork(object sender, DoWorkEventArgs e)
 {
        // do your task here
 }
 private void worker_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e)
 {

       //Do when completed 
 }
Metonym answered 22/7, 2016 at 5:12 Comment(1)
Your answer deviates from what OP is asking. He is using hangfire for background job processing. Using BackgroundWorked for this purpose would be a totally different thing.Thunderhead

© 2022 - 2024 — McMap. All rights reserved.