1

I have a hopefully a simple question to which i can't find the answer.

If i schedule a Job of type LongRunningAndHeavyJob on demand (StartNow()) i dont know how long this job will run but it can be long (from 10 minutes to 60+ minutes) and is very CPU intensive. Because the end-users can start this job on demand i want to make sure only one instance of this job is running at a certain time.

So for example:

  1. John click on button schedule at 14:00:00
  2. Quartz.net server will run this job
  3. Jane clicks on the button schedule at 14:05:00 but the job of John is still running

How can i make sure that the job of Jane will not run at the same time with the job of John and will run after the job of John is finished.

The attribute DisallowConcurrentExecution is only for use if you have a job that is schedule with a trigger that is repeating i think and the job need to have the same key which i don't have.

Some extra info: Job of John has different JobData than the job of Jane

Thanks in advance

Jordy van Eijk
  • 2,718
  • 2
  • 19
  • 37
  • 1
    You are right `DisallowConcurrentExecution` is useless in your case. You can take a look [here](https://stackoverflow.com/a/45813648/6666799), this is a similar issue to yours where i described how to solve this problem. – Rabban Sep 28 '17 at 08:59
  • @Rabban thank you for pointing me in this direction but this is not exactly what i'm looking for. I Fixed it for now differently I will soon post the answer – Jordy van Eijk Sep 28 '17 at 09:50

1 Answers1

3

I fixed the problem that i was facing!

How did i do it:

  1. Decorated the Long running jobs with the [DisallowConcurrentExecution] attribute
  2. When the Quartz server is starting i add the long running jobs as Durable jobs without any trigger.
  3. After someone requests the job to run i will set the JobData on the trigger instead of the job and schedule the job by only giving the trigger to the ScheduleJob method (trigger uses ForJob(IJobDetail) method)

This will make sure only 1 instance of the Job will be running at a given time and if someone else triggers the same job it will be scheduled to run after the first one is completed and there are thread in the threadpool available

Server part:

private void RegisterManualJobs() {
  var createTournamentScheduleJob = JobBuilder.Create<CreateTournamentScheduleJob>().WithIdentity("CreateTournamentSchedule", JobGroups.JG_TournamentScheduleJobs).StoreDurably().Build();
  var createTournamentScheduleSingleEventJob = JobBuilder.Create<CreateTournamentScheduleSingleEventJob>().WithIdentity("CreateTournamentScheduleSingleEvent", JobGroups.JG_TournamentScheduleJobs).StoreDurably().Build();

  Scheduler.AddJob(createTournamentScheduleJob,true);
  Scheduler.AddJob(createTournamentScheduleSingleEventJob,true);
}

Client part:

var job = Scheduler.GetJobByName("CreateTournamentSchedule", JobGroups.JG_TournamentScheduleJobs);
var trigger = TriggerBuilder.Create().StartNow().WithIdentity($"Trigger-CreateTournamentSchedule-{TournamentID}", JobGroups.JG_TournamentScheduleJobs).UsingJobData(data).ForJob(job).Build();
Scheduler.ScheduleJob(trigger);

The GetJobByName() is one of the extensionmethods i wrote on the IScheduler

Jordy van Eijk
  • 2,718
  • 2
  • 19
  • 37