2

我一直在研究一个调度引擎,它从数据库中读取调度作业并安排它们工作正常但是数据库中的行只是某些类型作业的“配置”,例如:

获取 FTP 的特定配置有

host: imagineryHost1.com 
post: 22

另一个同级别的有

host: imagineryHost2.com
post: 21

我们使用自己的触发器和自己的单独数据创建两个 FPTjob。

/**
BaseJob is an Abstract class extending QuartzJobBean used to handle our logging and 
other requirements that need across all our jobs.
*/
public class FTPJob extends BaseJob {

    /**
        Called from executeInternal of QuartzJobBean 
    */
    @Override
    public boolean execute1V(JobExecutionContext context) {
        //Code to get Files from FTP.
    }
}

这些是使用带有 cron 的 TriggerBuilder 安排的。

如果我添加 @DisallowConcurrentExecution 将只允许我们的 FTPJob 的 1 个实例在任何时候运行,但是我需要能够运行 FTPJob 的多个实例,但仅限于该类的特定配置的一个实例。

任何有关如何取得进展的线索都将受到高度赞赏:)

更新

根据 ftom2 的回答,我去挖掘并找到了 TriggerListener,因为每个作业配置都有它自己的 uniqueID,所以我可以“否决”运行作业,即。

public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
    try {
        Iterator<JobExecutionContext> it =     
        context.getScheduler().getCurrentlyExecutingJobs().iterator();

        boolean found = false;
        while(it.hasNext()) {
            JobExecutionContext job = it.next();

            if(trigger.getJobKey().equals(job.getJobDetail().getKey())) {
                return false;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

有没有其他更内置的方法来处理这个问题?

4

3 回答 3

1

我不确定这是否可能,但这可能是一个方向。

您可以实现JobListener,然后执行以下操作:

  1. 使用 jobWasExecuted,您将在 jobDetails 中设置该作业完成的标志。
  2. 使用 jobToBeExecuted,您将在作业启动之前检查作业状态,看看它是否处于运行状态,如果是 - 停止它(请参阅此处),如果不是 - 让它运行并将其状态设置为运行。

希望这可以帮助。

于 2012-06-27T10:03:06.433 回答
0

很抱歉迟到了一年……但是建议使用 TriggerLinstener 不是非线程安全的吗?在我看来,两个工作可以在 getCurrentlyExecutingJobs() 返回之前通过否决阶段。在同样的情况下,我在调度程序上使用了执行锁,它甚至更少“内置”......(想法是 - 尝试在触发器 linstener 中获取锁,如果不能,则否决,从作业侦听器 jobWasExecuted 返回锁)。

于 2013-07-10T12:04:05.497 回答
0

看起来有状态的作业不允许并发执行,你可以简单地实现 StatefulJob 而不是 Job 接口

于 2014-05-21T19:10:30.410 回答