quartz可以实现延迟_在Quartz.net中,如何将所有计划的作业延迟一定时间?

该博客讨论了如何在使用Quartz.net进行任务调度时,当API请求达到限制并被限速时,如何优雅地暂停所有计划任务。作者提出实现ITriggerListener接口并使用VetoJobExecution方法来阻止任务执行,或者在任务开始时检查系统状态,如果被限速则抛出JobExecutionException。这两种方法都可以确保在系统被限速期间避免触发新的任务执行。
摘要由CSDN通过智能技术生成

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.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.

You can implement the ITriggerListener interface and use the VetoJobExecution() method. The implementation can look like this:

public class SystemThrottledTriggerListener : ITriggerListener

{

public string Name => "System Throttled Trigger Listener";

public void TriggerComplete(ITrigger trigger, IJobExecutionContext context, SchedulerInstruction triggerInstructionCode)

{

// no need for implementation

}

public void TriggerFired(ITrigger trigger, IJobExecutionContext context)

{

// no need for implementation

}

public void TriggerMisfired(ITrigger trigger)

{

// no need for implementation

}

public bool VetoJobExecution(ITrigger trigger, IJobExecutionContext context)

{

// If you return true, then the Trigger is vetoed and the job is not executed.

// The Job will automatically scheduled for his next execution

return IsSystemThrottled();

}

}

Then simply add the Listener to your scheduler and all triggers are vetoed if your system is throttled:

Scheduler.ListenerManager.AddTriggerListener(new SystemThrottledTriggerListener());

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:

public class MyJob : IJob

{

public void Execute(IJobExecutionContext context)

{

if(IsSystemThrottled())

throw new JobExecutionException(true);

// your other stuff

}

}

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.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值