手动将 Cron-Job 添加到池中

Posted

技术标签:

【中文标题】手动将 Cron-Job 添加到池中【英文标题】:Add Cron-Job manually to the pool 【发布时间】:2012-08-08 07:10:20 【问题描述】:

我想做以下事情:

通常,您通过实现一个扩展 http://www.playframework.org/documentation/api/1.2.4/play/jobs/Job.html 的类来实现 Play-Jobs,该 http://www.playframework.org/documentation/api/1.2.4/play/jobs/Job.html 添加到池 OnApplicationStart...

我现在想在运行时添加 Cron-Jobs(通过 GUI 添加任务...),但我不确定如何实现。

我查看了 JobsPlugin 并发现以下几行:

job.nextPlannedExecution = nextDate;
executor.schedule((Callable<V>)job, nextDate.getTime() - now.getTime(), TimeUnit.MILLISECONDS);
job.executor = executor;

我必须像那样添加它们吗?

这可能吗?因为我找不到任何行,告诉作业本身,它应该遵循哪个 Cron-Expression...

String cron = job.getClass().getAnnotation(On.class).value();

在 Job-Execution 和新的job.nextPlannedExecution 设置后,这条线是否再次从外部调用?


好的,我希望我现在不回答我自己的问题,但这是否是解决方案?:

我实现了自己的 Job-Class,添加了一个属性,例如cronExpression 并覆盖作业的

public void _finally() 
    super._finally();
    if (executor == JobsPlugin.executor) 
        JobsPlugin.scheduleForCRON(this);
    

实现我自己的sheduleForCron()

【问题讨论】:

【参考方案1】:

查看 JobsPlugin 的源代码,您应该能够模仿使用 scheduledJobsexecutor 属性所做的事情。

如果你看一下onApplicationStart 方法,这显示了用@On 或'@Everyare managed in the job pool.Onuses the CRON expression and usesscheduleForCRON, where asEvery` 注释的作业如何使用执行器来管理重复。

由于scheduledJobsexecutor 属性是public static,你可以随意访问和操作它,所以我建议阅读JobsPlugin 的源代码,尤其是下面的代码,并模仿它在你自己的代码库中。

        // @On
        if (clazz.isAnnotationPresent(On.class)) 
            try 
                Job<?> job = ((Job<?>) clazz.newInstance());
                scheduledJobs.add(job);
                scheduleForCRON(job);
             catch (InstantiationException ex) 
                throw new UnexpectedException("Cannot instanciate Job " + clazz.getName());
             catch (IllegalAccessException ex) 
                throw new UnexpectedException("Cannot instanciate Job " + clazz.getName());
            
        
        // @Every
        if (clazz.isAnnotationPresent(Every.class)) 
            try 
                Job job = (Job) clazz.newInstance();
                scheduledJobs.add(job);
                String value = job.getClass().getAnnotation(Every.class).value();
                if (value.startsWith("cron.")) 
                    value = Play.configuration.getProperty(value);
                
                value = Expression.evaluate(value, value).toString();
                if(!"never".equalsIgnoreCase(value))
                    executor.scheduleWithFixedDelay(job, Time.parseDuration(value), Time.parseDuration(value), TimeUnit.SECONDS);
                
             catch (InstantiationException ex) 
                throw new UnexpectedException("Cannot instanciate Job " + clazz.getName());
             catch (IllegalAccessException ex) 
                throw new UnexpectedException("Cannot instanciate Job " + clazz.getName());
            
        

【讨论】:

我认为 sheduledJobs 只是用于调试目的.. 导致它除了在 getStatus() 方法中打印一些东西外无处使用...... exectuor.sheduleWithFixedDelay() 添加了一个周期性动作,而 excetuor.shedule () 具有未来延迟的单个动作 所以,由于您可以直接访问执行器,因此您几乎可以启动任何您想要的工作。

以上是关于手动将 Cron-Job 添加到池中的主要内容,如果未能解决你的问题,请参考以下文章

Python中的多处理:处理多个工作线程

在 Objective-C 中如何处理 Autorelease 池中的对象?

在函数内部的python中将元素添加到池数组

Java Connection Pool 和 try-with 语句:连接实际上是关闭还是返回到池中?

Kubernetes Cron-Job闲置通知

JVM学习分享-思考题