如何找到计划任务的下一个运行时间? [英] How do I find out the next run time for a Scheduled Task?

查看:189
本文介绍了如何找到计划任务的下一个运行时间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在ColdFusion 9中,有没有一个快速的方法来查找下一次计划的任务将尝试运行?

解决方案

< blockquote>

我宁愿调用一个较低级别的API,或者让CF计算它
的方式与通常情况相同。我抛弃了各种服务
,没有明显的方法来调用,这将有所帮助。


AFAIK,一线解决方案。 CF用来计算日期的主要方法是 CronTabEntry.NextRunTime CronTabEntry 类表示单个任务的设置。 NextRunTime 方法根据任务的设置计算下一个潜在的运行日期。过期和暂停的任务的处理在其他地方,在运行时完成。



要复制结果,您需要调用 NextRunTime 并添加一点逻辑来处理过期的任务。虽然 NextRunTime 方法是私有的,但仍然可以通过反射访问,借助 Method.setAccessible(boolean)



我把下面的函数放在一起来演示。它的大部分是反射调用(这是一个比在其等同的java更冗长的CF)。无论如何,它应该返回与CF调度程序使用的相同的日期。



规则




  • 日期/时间已过,返回一个emtpy字符串

  • 如果是一次性任务,则已执行,返回一个空字符串

  •   result = new TaskUtil()。getNextRunTime(SomeTask); 
    WriteDump(result);

    CFC

     组件{
    public struct function getNextRunTime(required string scheduledTaskName){

    //从工厂加载任务设置
    local.cron = createobject(java,coldfusion.server.ServiceFactory)。getCronService();
    local.task = local.cron.findTask(arguments.scheduledTaskName);

    //如果我们找不到任务,则中止。
    if(isNull(local.task)){
    throw(找不到指定的任务: ; arguments.scheduledTaskName&]);
    }

    //计算下一个POTENTIAL调度日期
    local.isRecurring = listFindNoCase(daily,weekly,monthly,local.task.interval);
    local.dateClass = createObject(java,java.util.Date)。getClass();
    local.longClass = createObject(java,java.lang.Long)。
    local.stringClass = createObject(java,java.lang.String)。getClass();

    //构造适当的参数
    //注意:必须将参数/类类型加载到数组中以进行java反射
    if(local.isRecurring){
    local。 args = [local.task.getStartDate(),local.task.getStartTime(),local.task.interval];
    local.types = [local.dateClass,local.dateClass,local.stringClass];
    }
    else {
    local.args = [local.task.getStartDate(),local.task.getStartTime(),local.task.getEndTime(),javacast(long val(local.task.interval)* 1000)];
    local.types = [local.dateClass,local.dateClass,local.dateClass,local.longClass];
    }

    //调用CF的内部方法来计算下一个日期(UNDOCUMENTED)
    local.internalMethod = local.task.getClass()。getDeclaredMethod(NextRunTime,local .types);
    local.internalMethod.setAccessible(true);
    local.nextRunOnDate = local.internalMethod.invoke(local.task,local.args);

    //确定任务是否将被重新调度
    local.isExpired = false;
    if(local.task.interval!=once&&& structKeyExists(local.task,end_date)){
    //它是非循环的,因此确定它是否已经过期
    local.expiresOnDate = local.task.mergeDates(local.task.getEndDate(),local.task.getEndTime());
    local.isExpired = dateCompare(local.nextRunOnDate,local.expiresOnDate,s)> = 0;
    }
    else if(local.task.interval ==once&& local.task.disabled){
    //这是已执行的一次性任务
    local.isExpired = true;
    }

    //构造并返回结果
    local.result = {};
    local.result.name = local.task.task;
    local.result.isPaused = local.task.paused;
    local.result.isExpired = local.isExpired;
    local.result.nextRunTime = local.isExpired? :local.nextRunOnDate;

    return local.result;
    }
    }


    In ColdFusion 9, is there a quick way to find out the next time that a scheduled task will attempt to run?

    解决方案

    I would rather call a lower level API or such to have CF calculate it in the same way it normally would. I've dumped the various services and see no obvious methods to call that would help.

    AFAIK, there is no one line solution. The main method CF uses to calculate the dates is CronTabEntry.NextRunTime. The CronTabEntry class represents the settings for a single task. The NextRunTime method(s) calculate the next potential run date, based on the task's settings. Handling of expired and paused tasks is done elsewhere, at runtime.

    To duplicate the results you need to call NextRunTime and add a bit of logic to handle expired tasks. While NextRunTime method is private, it can still be accessed via reflection, with the help of Method.setAccessible(boolean).

    I threw together the function below to demonstrate. The bulk of it is the reflection call (which is a bit more verbose in CF than its java equivalent). Anyway, it should return the same dates used by the CF scheduler.

    Rules:

    • If the task end date/time has passed, returns an emtpy string ""
    • If it is a one-time task, that already executed, returns an empty string ""
    • For all other tasks (including paused tasks), returns the next scheduled date

    Usage:

    result = new TaskUtil().getNextRunTime("SomeTask");
    WriteDump(result);
    

    CFC

    component {
         public struct function getNextRunTime(required string scheduledTaskName) {
    
            // load task settings from factory
            local.cron = createobject("java","coldfusion.server.ServiceFactory").getCronService();
            local.task = local.cron.findTask( arguments.scheduledTaskName );
    
            // abort if we cannot find the task ..
            if ( isNull(local.task) ) {
                throw ("The specified task was not found: ["& arguments.scheduledTaskName &"]");
            }     
    
            // Calculate the next POTENTIAL schedule date 
            local.isRecurring = listFindNoCase("daily,weekly,monthly", local.task.interval);
            local.dateClass   = createObject("java", "java.util.Date").getClass();
            local.longClass   = createObject("java", "java.lang.Long").TYPE;
            local.stringClass = createObject("java", "java.lang.String").getClass();
    
            // Construct the appropriate arguments 
            // Note: must load arguments / class types into arrays for java reflection 
            if (local.isRecurring) {
                local.args  = [ local.task.getStartDate(), local.task.getStartTime(), local.task.interval ];
                local.types = [ local.dateClass, local.dateClass, local.stringClass ];
            }
            else {
                local.args  = [ local.task.getStartDate(), local.task.getStartTime(), local.task.getEndTime(), javacast("long", val(local.task.interval) * 1000) ];
                local.types = [ local.dateClass, local.dateClass, local.dateClass, local.longClass ];
            }
    
            // Call CF's internal method to calculate the next date (UNDOCUMENTED)    
            local.internalMethod = local.task.getClass().getDeclaredMethod("NextRunTime", local.types );
            local.internalMethod.setAccessible( true );
            local.nextRunOnDate = local.internalMethod.invoke( local.task, local.args );
    
            // Determine if the task will be rescheduled
            local.isExpired   = false;
            if ( local.task.interval != "once" && structKeyExists( local.task, "end_date") ) {
                // It is non-recurring, so determine if it already expired
                local.expiresOnDate = local.task.mergeDates( local.task.getEndDate(), local.task.getEndTime() );
                local.isExpired   = dateCompare( local.nextRunOnDate, local.expiresOnDate, "s") >= 0;
            }
            else if ( local.task.interval == "once" && local.task.disabled) {
                // It is a one time task that already executed
                local.isExpired   = true;
            }
    
            // construct and return results    
            local.result = {};
            local.result.name          = local.task.task;
            local.result.isPaused    = local.task.paused;
            local.result.isExpired   = local.isExpired;
            local.result.nextRunTime = local.isExpired ? "" : local.nextRunOnDate;
    
            return local.result;
        }    
    }
    

    这篇关于如何找到计划任务的下一个运行时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆