How do I know the next runtime for a scheduled task?

In ColdFusion 9, is there a quick way to find out the next time a scheduled task tries to start?

+4
source share
1 answer

I would prefer to call the API lower level or one to calculate its CF in the same way as usual. I quit various services and do not see obvious calling methods that could help.

AFAIK, there is not a single linear solution. The main CF method is used to calculate the dates of CronTabEntry.NextRunTime . The CronTabEntry class represents options for a single task. The NextRunTime method calculates the next potential NextRunTime date based on the task settings. Outdated and paused tasks are handled elsewhere at run time.

To duplicate the results, you must call NextRunTime and add a bit of logic to handle expired tasks. Although the NextRunTime method is private, it can still be accessed through reflection using Method.setAccessible (boolean) .

I put together the function below to demonstrate. Its main part is the call to reflection (which is a bit more verbose in CF than its java equivalent). In any case, it should return the same dates used by the CF scheduler.

Rules:

  • If the task completion date / time has passed, returns the string emtpy ""
  • If this is a one-time task that has already been completed, returns an empty string ""
  • For all other tasks (including suspended tasks) returns the next scheduled date

Application:

 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 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; } } 
+5
source

Source: https://habr.com/ru/post/1414174/


All Articles