arlut.csd.ganymede
Class GanymedeScheduler

java.lang.Object
  |
  +--java.lang.Thread
        |
        +--arlut.csd.ganymede.GanymedeScheduler
All Implemented Interfaces:
java.lang.Runnable

public class GanymedeScheduler
extends java.lang.Thread

Background task scheduler for the Ganymede server. It is similar in function and behavior to the UNIX cron facility, but is designed to run arbitrary Java Runnable objects in separate threads within the server.

The Ganymede server's main() routine creates a GanymedeScheduler at server start time. Once created, the server's GanymedeScheduler runs as an asynchronous thread, sleeping until a task is scheduled to be run. GanymedeScheduler is designed to operate in a multi-threaded fashion, with a background task executing the run() method spending most of its time waiting for something to happen, and various scheduling methods being called interactively to change the behavior of the run() method's on-going execution. (I.e., to schedule new tasks or to change task scheduling)

The GanymedeScheduler tracks tasks by name. Only one task with a given name may be registered with the scheduler at a time. Registering a new task with a given name will cause the scheduler to forget about an old task by the same name.

GanymedeScheduler is closely bound to the scheduleHandle and taskMonitor classes. Together, these three classes form a robust and flexible task scheduling system.

The GanymedeScheduler supports updating the Ganymede admin console's task monitor display by way of the Admin interface. Likewise, the Ganymede server's admin console interface, GanymedeAdmin supports several remote methods that the admin console can call to affect GanymedeScheduler.


Field Summary
private  java.util.Hashtable currentlyRunning
           
private  java.util.Hashtable currentlyScheduled
           
(package private) static boolean debug
           
(package private) static boolean logStuff
           
(package private) static int minsPerDay
           
(package private)  java.util.Date nextAction
           
private  java.util.Hashtable onDemand
           
private  boolean reportTasks
          if true, the scheduler will attempt to notify the GanymedeAdmin class when tasks are scheduled and/or completed.
private  java.util.Vector taskList
           
private  boolean taskListInitialized
           
 
Fields inherited from class java.lang.Thread
contextClassLoader, daemon, eetop, group, inheritableThreadLocals, inheritedAccessControlContext, MAX_PRIORITY, MIN_PRIORITY, name, NORM_PRIORITY, priority, single_step, stillborn, stopThreadPermission, target, threadInitNumber, threadLocals, threadQ
 
Constructor Summary
GanymedeScheduler(boolean reportTasks)
          Constructor
 
Method Summary
 void addActionOnDemand(java.lang.Runnable task, java.lang.String name)
          This method is used to add a task to the scheduler that will not be scheduled until specifically requested.
 void addDailyAction(int hour, int minute, java.lang.Runnable task, java.lang.String name)
          This method is used to add an action to be run every day at a specific time.
 void addPeriodicAction(java.util.Date firstTime, int intervalMinutes, java.lang.Runnable task, java.lang.String name)
          This method is used to add an action to be run at a specific initial time, and every <intervalMinutes> thereafter.
 void addTimedAction(java.util.Date time, java.lang.Runnable task, java.lang.String name)
          This method is used to add an action to be run once, at a specific time.
private  void cleanUp()
          This method is run when the GanymedeScheduler thread is terminated.
 boolean demandTask(java.lang.String name)
          This method is provided to allow the server to request that a task listed as being registered 'on-demand' be run as soon as possible.
 boolean demandTask(java.lang.String name, java.lang.Object[] options)
          This method is provided to allow the server to request that a task listed as being registered 'on-demand' be run as soon as possible.
 boolean disableTask(java.lang.String name)
          This method is provided to allow an admin console to specify that a task be suspended.
 boolean enableTask(java.lang.String name)
          This method is provided to allow an admin console to specify that a task be re-enabled after a suspension.
static void main(java.lang.String[] argv)
          Debug rig
(package private)  void notifyCompletion(scheduleHandle handle)
          This method is used by instances of scheduleHandle to let the GanymedeScheduler thread know when their tasks have run to completion.
 void registerTaskObject(DBObject object)
          This method is used to register a task DBObject record from the Ganymede database in this scheduler, loading the named Runnable class via the Java class loader and scheduling the Runnable for execution according to the parameters specified in the task object.
(package private)  java.util.Vector reportTaskInfo()
          Returns a Vector of scheduleHandle objects suitable for reporting to the admin console.
 void run()
          This method is responsible for carrying out the scheduling work of this class on a background thread.
private  void runTask(scheduleHandle handle)
          This private method is used by the GanymedeScheduler thread's main loop to put a task in the scheduled hash onto the run hash
 boolean runTaskNow(java.lang.String name)
          This method is provided to allow an admin console to cause a registered task to be immediately spawned.
private  void scheduleTask(scheduleHandle handle)
          This private method takes a task that needs to be scheduled and adds it to the scheduler.
 boolean stopTask(java.lang.String name)
          This method is provided to allow an admin console to put an immediate halt to a running background task.
 scheduleHandle unregisterTask(java.lang.String name)
          This method unregisters the named task so that it can be rescheduled with different parameters, or simply removed.
private  void updateTaskInfo(boolean updateConsoles)
          This method is used to report to the Ganymede server (and thence the admin console(s) the status of background tasks scheduled and/or running.
 
Methods inherited from class java.lang.Thread
, activeCount, checkAccess, countStackFrames, currentThread, destroy, dumpStack, enumerate, exit, getContextClassLoader, getName, getPriority, getThreadGroup, init, interrupt, interrupt0, interrupted, isAlive, isDaemon, isInterrupted, isInterrupted, join, join, join, nextThreadNum, registerNatives, resume, resume0, setContextClassLoader, setDaemon, setName, setPriority, setPriority0, sleep, sleep, start, stop, stop, stop0, suspend, suspend0, toString, yield
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

minsPerDay

static final int minsPerDay

debug

static final boolean debug

logStuff

static final boolean logStuff

nextAction

java.util.Date nextAction

currentlyScheduled

private java.util.Hashtable currentlyScheduled

currentlyRunning

private java.util.Hashtable currentlyRunning

onDemand

private java.util.Hashtable onDemand

taskList

private java.util.Vector taskList

taskListInitialized

private boolean taskListInitialized

reportTasks

private boolean reportTasks
if true, the scheduler will attempt to notify the GanymedeAdmin class when tasks are scheduled and/or completed.
Constructor Detail

GanymedeScheduler

public GanymedeScheduler(boolean reportTasks)
Constructor
Parameters:
reportTasks - if true, the scheduler will attempt to notify the GanymedeAdmin class when tasks are scheduled and/or completed.
Method Detail

main

public static void main(java.lang.String[] argv)
Debug rig

registerTaskObject

public void registerTaskObject(DBObject object)

This method is used to register a task DBObject record from the Ganymede database in this scheduler, loading the named Runnable class via the Java class loader and scheduling the Runnable for execution according to the parameters specified in the task object.


addActionOnDemand

public void addActionOnDemand(java.lang.Runnable task,
                              java.lang.String name)

This method is used to add a task to the scheduler that will not be scheduled until specifically requested.

If a task with the given name is already registered with the scheduler, that task will be removed from the scheduling queue and registered anew as an on-demand task.


addTimedAction

public void addTimedAction(java.util.Date time,
                           java.lang.Runnable task,
                           java.lang.String name)

This method is used to add an action to be run once, at a specific time.

If a task with the given name is already registered with the scheduler, that task will be removed from the scheduling queue and registered anew as a single-execution task.


addDailyAction

public void addDailyAction(int hour,
                           int minute,
                           java.lang.Runnable task,
                           java.lang.String name)

This method is used to add an action to be run every day at a specific time.

If a task with the given name is already registered with the scheduler, that task will be removed from the scheduling queue and registered anew as a periodic task.


addPeriodicAction

public void addPeriodicAction(java.util.Date firstTime,
                              int intervalMinutes,
                              java.lang.Runnable task,
                              java.lang.String name)

This method is used to add an action to be run at a specific initial time, and every <intervalMinutes> thereafter.

The scheduler will not reschedule a task until the last scheduled instance of the task has completed.

If a task with the given name is already registered with the scheduler, that task will be removed from the scheduling queue and registered anew as a periodic task.


unregisterTask

public scheduleHandle unregisterTask(java.lang.String name)

This method unregisters the named task so that it can be rescheduled with different parameters, or simply removed.

Note that this method will not prevent the scheduler's run() method from briefly waking up unnecessarily if the named task was the next scheduled to be executed. Easier to have the run() method check to see if any tasks actually need to be run than to try and persuade the run() method not to wake up for the removed task.


runTaskNow

public boolean runTaskNow(java.lang.String name)

This method is provided to allow an admin console to cause a registered task to be immediately spawned.

Returns:
true if the task is either currently running or was started, or false if the task could not be found in the list of currently registered tasks.

demandTask

public boolean demandTask(java.lang.String name)

This method is provided to allow the server to request that a task listed as being registered 'on-demand' be run as soon as possible.

If the task is currently running, it will be flagged to run again as soon as the current run completes. This is intended to support the need for the server to be able to do back-to-back nis/dns builds.

Returns:
false if the task name could not be found on the on-demand or currently running lists.

demandTask

public boolean demandTask(java.lang.String name,
                          java.lang.Object[] options)

This method is provided to allow the server to request that a task listed as being registered 'on-demand' be run as soon as possible.

If the task is currently running, it will be flagged to run again as soon as the current run completes. This is intended to support the need for the server to be able to do back-to-back nis/dns builds.

Returns:
false if the task name could not be found on the on-demand or currently running lists.

stopTask

public boolean stopTask(java.lang.String name)

This method is provided to allow an admin console to put an immediate halt to a running background task.

Returns:
true if the task was either not running, or was running and was told to stop.

disableTask

public boolean disableTask(java.lang.String name)

This method is provided to allow an admin console to specify that a task be suspended. Suspended tasks will not be scheduled until later enabled. If the task is currently running, it will not be interfered with, but the task will not be scheduled for execution in future until re-enabled.

Returns:
true if the task was found and disabled

enableTask

public boolean enableTask(java.lang.String name)

This method is provided to allow an admin console to specify that a task be re-enabled after a suspension.

A re-enabled task will be scheduled for execution according to its original schedule, with any runtimes that would have been issued during the time the task was suspended simply skipped.

Returns:
true if the task was found and enabled

run

public void run()

This method is responsible for carrying out the scheduling work of this class on a background thread.

The basic logic is to wait until the next action is due to run, move the task from our scheduled list to our running list, and run it. Other synchronized methods such as runTask(), scheduleTask(), and notifyCompletion(), may be called while this method is waiting for something to happen. These methods modify the data structures that run() uses to determine its scheduling needs.

Overrides:
run in class java.lang.Thread

runTask

private void runTask(scheduleHandle handle)

This private method is used by the GanymedeScheduler thread's main loop to put a task in the scheduled hash onto the run hash


notifyCompletion

void notifyCompletion(scheduleHandle handle)

This method is used by instances of scheduleHandle to let the GanymedeScheduler thread know when their tasks have run to completion. This method is responsible for rescheduling the task if it is a periodic task.


scheduleTask

private void scheduleTask(scheduleHandle handle)

This private method takes a task that needs to be scheduled and adds it to the scheduler. All scheduling additions or changes are handled by this method. This is the only method in GanymedeScheduler that can notify the run() method that it may need to wake up early to handle a newly registered task.


cleanUp

private void cleanUp()

This method is run when the GanymedeScheduler thread is terminated. It kills off any background processes currently running. Those threads should have a finally clause that can handle abrupt termination.


updateTaskInfo

private void updateTaskInfo(boolean updateConsoles)

This method is used to report to the Ganymede server (and thence the admin console(s) the status of background tasks scheduled and/or running.


reportTaskInfo

java.util.Vector reportTaskInfo()

Returns a Vector of scheduleHandle objects suitable for reporting to the admin console.