问题
This thread was useful in finding out the next run-time for a scheduled task.
How do I find out the next run time for a Scheduled Task?
But, is there also a way to simply get the next scheduled task due to run?
If I can get the date and name of the next task due to run, I can plug that date into a jQuery countdown timer, which will display a countdown to the next scheduled task, something like:
TaskABC due to run in:
12 03 20
hrs min sec
. This is for an admin interface in case you're wondering how geeky can people get:-)
EDIT
回答1:
I had the same thought as Bill. But was curious if there was another way.
I poked around 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 like the mail spooler, session/application trackers, watchers, etecetera. So you must iterate through it until you find a "scheduled task" ie CronTabEntry
Below is a very lightly tested function that seems to do the trick in CF9. (Note, includes 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 were found,
result.task
is an empty string. - Excludes paused tasks
Usage:
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;
}
}
回答2:
My first thought is to iterate Leigh's getNextRunTime(string taskName)
function over the collection of tasks. You can get an array of structs containing the details of all scheduled tasks using taskArray = createobject("java","coldfusion.server.ServiceFactory").getCronService().listAll();
The key in the struct containing the task name is "task". So you can extract all the task names as an array for example, run Leigh's function on each element and determine which one will run next.
来源:https://stackoverflow.com/questions/12399616/coldfusion-get-next-scheduled-task-due-to-run