I am using Quartz.net to schedule various API calls. The API I am using restricts the number of requests that can be made per time period and if that is exceeded, then my account is penalized for the next minute (no requests can be made).
If I ever receive a notification that I have made too many requests and my account will be throttled for the next minute, I will need to ensure that no scheduled jobs fire during that period. How can I best delay firing of all scheduled jobs by a minute or two?
I was originally intending to call Scheduler.GetTriggerKeys() and loop over and update every existing trigger like so:
foreach(var triggerKey in SchedInstance.GetTriggerKeys(GroupMatcher<TriggerKey>.AnyGroup()))
{
var oldTrigger = SchedInstance.GetTrigger(triggerKey);
TriggerBuilder tb = oldTrigger.GetTriggerBuilder();
// Update the schedule associated with the builder and build the new trigger
tb.StartAt(oldTrigger.StartTimeUtc.AddSeconds(63));
var newTrigger = tb.Build();
SchedInstance.RescheduleJob(oldTrigger.Key, newTrigger);
}
Is this the right approach or would it be better to simply stop the scheduler for the same time period and then restart it?
You have a couple of possibilities to achieve that. As you stated, you can stop the scheduler or loop over your triggers. But this sounds for me not like the best option.
TriggerListener
You can implement the
ITriggerListener
interface and use theVetoJobExecution()
method. The implementation can look like this:Then simply add the Listener to your scheduler and all triggers are vetoed if your system is throttled:
JobExecutionException
You can throw a
JobExecutionException
to stop the execution of your job. To do this, you need to check at the beginning of the execution that your system is throttled and then throw the exeception. This is the only exception for Quartz at which you can tell Quartz that it should refire the job immediately. All other exceptions will be swallowed and will stop the execution of the job. The implementation can look like this:If you create the exception with the parameter
true
, the job will immediately refired. And will refired again and again until your system is no longer throttled.If you have many jobs, i would recommend to use a job base class that can throw the JobExecutionException and you derive your jobs only from this class.