I had the same thought as Bill. But it was curious if there was another way.
I poked and apparently the internal Scheduler
class maintains a list of upcoming tasks. The list is private, but you can use the same reflection technique to access it. Interestingly, the list also includes system tasks, such as message queue manager, session / application trackers, observers, etecetera. So you have to go through it until you find the "scheduled task", that is, CronTabEntry
Below is a very poorly tested feature that seems to do the trick in CF9. (Note: Enables the CreateTimeStruct function from http://www.cflib.org ).
Rules:
- Returns a structure containing the name and time remaining until the next task. If no tasks are found,
result.task
is an empty string. - Excludes suspended tasks
Application:
result = new TaskUtil().getNextTask(); WriteDump(result);
Cfc
component { public struct function getNextTask() { // get list of upcoming tasks from factory (UNDOCUMENTED) local.scheduler = createObject("java", "coldfusion.server.ServiceFactory").getSchedulerService(); local.taskField = local.scheduler.getClass().getDeclaredField("_tasks"); local.taskField.setAccessible( true ); local.taskList = local.taskField.get(local.scheduler); // taskList contains system jobs too, so we must iterate // through the tasks to find the next "scheduled task" local.nextTask = ""; local.tasks = local.taskList.iterator(); while ( local.tasks.hasNext() ) { local.currTask = local.tasks.next(); local.className = local.currTask.getRunnable().getClass().name; // exit as soon as we find a scheduled task that is NOT paused if (local.className eq "coldfusion.scheduling.CronTabEntry" && !local.currTask.getRunnable().paused) { local.nextTask = local.currTask; break; } } // if we found a task, calculate how many days, hours, etcetera // until its next run time local.details = { task="", remaining={} }; if ( isObject(local.nextTask) ) { local.secondsToGo = (local.nextTask.getWhen() - now().getTime()) / 1000; local.details.task = local.nextTask.getRunnable().task; local.details.remaining = createTimeStruct(local.secondsToGo); local.details.nextDate = dateAdd("s", local.nextTask.getWhen() / 1000 , "January 1 1970 00:00:00" ); } return local.details; } /** * Abbreviated version of CreateTimeStruct by Dave Pomerance * See http://www.cflib.org/index.cfm?event=page.udfbyid&udfid=421 * * @param timespan The timespan to convert. * @return Returns a structure. * @author Dave Pomerance * @version 1, January 7, 2002 */ public struct function CreateTimeStruct(required numeric timespan) { var timestruct = StructNew(); var mask = "s"; // only 4 allowed values for mask - if not one of those, return blank struct if (ListFind("d,h,m,s", mask)) { // compute seconds if (mask eq "s") { timestruct.s = (timespan mod 60) + (timespan - Int(timespan)); timespan = int(timespan/60); mask = "m"; } else timestruct.s = 0; // compute minutes if (mask eq "m") { timestruct.m = timespan mod 60; timespan = int(timespan/60); mask = "h"; } else timestruct.m = 0; // compute hours, days if (mask eq "h") { timestruct.h = timespan mod 24; timestruct.d = int(timespan/24); } else { timestruct.h = 0; timestruct.d = timespan; } } return timestruct; } }
Leigh source share