FileDocCategorySizeDatePackage
PeriodicEventScheduler.javaAPI DocGlassfish v2 API12100Fri May 04 22:32:18 BST 2007com.sun.enterprise.util.scheduler

PeriodicEventScheduler

public class PeriodicEventScheduler extends Object implements Runnable
PeriodicEventScheduler manages tasks of the type PeriodicallyServicable. Such objects can be added to the manager and the time interval in these objects defines at what frequency the service() method of these tasks gets invoked by the manager.
It is critical that the service() operation be as brisk as possible for the manager to work effectively.
PeriodicEventScheduler is internally set as daemon.
$Source: /cvs/glassfish/appserv-commons/src/java/com/sun/enterprise/util/scheduler/PeriodicEventScheduler.java,v $
author
$Author: tcfujii $
version
1.0 $Revision: 1.4 $ $Date: 2007/05/05 05:32:17 $
see
PeriodicallyServicable

Fields Summary
static Logger
_logger
protected Thread
_thread
Internal Thread holder
private static PeriodicEventScheduler
_instance
Scheduler instance holder
private static Object
instanceLock
Instance lock
protected TimedTaskList
sortedList
Sorted task list
protected boolean
bRun
Thread runs while bRun is true (unless shutdown)
protected boolean
bDebug
Debug flag
protected transient long
counter
Current time holder
protected long
delay_time_approx
Delay for time approximation
protected com.sun.enterprise.util.ApproximateClock
clock
Approximate clock holder
private PeriodicallyServicable
executingTask
Maintained by the run() method
private boolean
removeExecutingTask
On remove, a check is made if the executingTask is the one to be removed. This is the flag set.
Constructors Summary
private PeriodicEventScheduler()
Constructor invoked once for the singleton.

        super();
        bRun = true;
        sortedList = new TimedTaskList();
        clock = new ApproximateClock (delay_time_approx);
        counter = getTime();
        _thread = new Thread (this, "PeriodicEventScheduler");
		_thread.setDaemon(true);
		_thread.start();
    
Methods Summary
public synchronized booleanaddTimeRepeatableTask(PeriodicallyServicable obj, int startingTime)
Add a PeriodicallyServicable object to the 'timed task execution queue'.

param
seconds time in seconds after which the task will be invoked for the first time. Do not confuse with the frequency period which is given by the getTimeIntervalForService() method on this object.
param
obj object that has to be serviced in timed interval fashion.
param
startingTime start calling service() method in startingTime + frequency time.
return
boolean true on success, false otherwise

        if(startingTime < 0 || obj.getFrequency() < 1)
        {
//Bug 4677074            if(bDebug) System.out.println("PeriodicEventScheduler::addTimeRepeatableTask() rejected task" + obj.toString());
//Bug 4677074 begin
	    if(com.sun.enterprise.util.logging.Debug.enabled) _logger.log(Level.FINE,"PeriodicEventScheduler::addTimeRepeatableTask() rejected task" + obj.toString());
//Bug 4677074 end

            return false;
        }
        boolean bool = sortedList.addTask(obj, startingTime, counter);
        synchronized(instanceLock)
        {
            instanceLock.notify();
        }
        return bool;
    
public static com.sun.enterprise.util.scheduler.PeriodicEventSchedulergetInstance()
Method to access the PeriodicEventScheduler singleton.

return
singleton object.


    
    
        _instance = new PeriodicEventScheduler();
    
        return _instance;   
    
private longgetTime()
Get approximate or actual time.

return
long current time.

        return clock.getActualTime(); // TODO : change actual time to perhaps approx time
    
protected synchronized booleaninsertSorted(TaskData taskObj)
Insert the task object into the task list.

param
taskObj task object to insert.
return
boolean true on success, false otherwise

        return sortedList.insertTask(taskObj);
    
public synchronized booleanremoveTimeRepeatableTask(PeriodicallyServicable obj)
Remove the servicable object from the task list.

param
obj PeriodicallyServicable object to be removed from the task list.
return
boolean true on success, false otherwise

        if(executingTask.equals(obj))
        {
            removeExecutingTask=true;
            return true;
        }
        else
            return sortedList.removeTask(obj);            
    
public voidrun()
Start running the thread.

    
            
      
    
        TaskData task=null;

        while(bRun)
        {
            try
            {
                //if(bDebug) System.out.println("---run()" + sortedList.toString() + "---");
//Bug 4677074 begin
		//if(com.sun.enterprise.util.logging.Debug.enabled) _logger.log(Level.FINE,"---run()" + sortedList.toString() + "---");
//Bug 4677074 end
                task = sortedList.getFirstTask();
                //if(bDebug) System.out.println("---run()" + sortedList.toString() + "+++");
//Bug 4677074 begin
                //if(com.sun.enterprise.util.logging.Debug.enabled) _logger.log(Level.FINE,"---run()" + sortedList.toString() + "+++");
//Bug 4677074 end
                if(null==task)
                {
                    synchronized(instanceLock)
                    {
                        instanceLock.wait();
                        continue; // fetches a task
                    }
                }
                
                executingTask=task.obj;
                
                // got the first task
                counter = getTime();
                long sleepingTime = task.abs_execute_time - counter;
                if(sleepingTime > 0L)
                {
                    try
                    {
//Bug 4677074                        if(bDebug) System.out.println("Current time=" + (int)(counter/1000) + ", Sleeping for " + sleepingTime + " msec.");
//Bug 4677074 begin
			if(com.sun.enterprise.util.logging.Debug.enabled) _logger.log(Level.FINE,"Current time=" + (int)(counter/1000) + ", Sleeping for " + sleepingTime + " msec.");
//Bug 4677074 end
                        Thread.sleep( sleepingTime );
                    }
                    catch(InterruptedException ieInner)
                    {
//Bug 4677074                        if(bDebug) System.out.println("PeriodicEventScheduler::run() > " + ieInner);
//Bug 4677074 begin
			if(com.sun.enterprise.util.logging.Debug.enabled) _logger.log(Level.FINE,"PeriodicEventScheduler::run() > " + ieInner);
//Bug 4677074 end
                    }
                }else
                {
                    // a decision has to be made immediately if we want to execute 
                    // the task even if we missed the right time to execute it
                    if (!task.obj.getExecutionTolerance(Math.abs(sleepingTime)) )
                    {
//Bug 4677074                         if(bDebug) System.out.println("Missed scheduling for " + task.obj.toString());
//Bug 4677074 begin
			if(com.sun.enterprise.util.logging.Debug.enabled)  _logger.log(Level.FINE,"Missed scheduling for " + task.obj.toString());
//Bug 4677074 end
                        continue;
                    } else
                    {
//Bug 4677074                        if(bDebug) System.out.println("Executing after missing scheduling for " + task.obj.toString());
//Bug 4677074 begin
			if(com.sun.enterprise.util.logging.Debug.enabled) _logger.log(Level.FINE,"Executing after missing scheduling for " + task.obj.toString());
//Bug 4677074 end
                    }
                }
              
                // now we can execute this task in multiple ways, one is on this thread,
                // other is on other task queues (by putting this task on the front of the Q)
                task.obj.service();
                
            }catch(InterruptedException ieOuter)
            {
//Bug 4677074                if(bDebug) System.out.println("PeriodicEventScheduler::run() > " + ieOuter);
//Bug 4677074 begin
			if(com.sun.enterprise.util.logging.Debug.enabled)  _logger.log(Level.FINE,"PeriodicEventScheduler::run() > " + ieOuter);
//Bug 4677074 end
            }
            catch(Exception e)
            {
                System.out.println("PeriodicEventScheduler::run() > " + e);
//Bug 4677074 begin
		_logger.log(Level.WARNING,"iplanet_util.generic_exception",e);
//Bug 4677074 end
            }
            finally
            {
                if (null!=task)
                {
                    counter = getTime();
                    // now put this task back into the Q
                    task.abs_execute_time = counter;
                    //if(bDebug) System.out.println("Adding in list " + task.obj.toString());
//Bug 4677074 begin
		    //if(com.sun.enterprise.util.logging.Debug.enabled) _logger.log(Level.FINE,"Adding in list " + task.obj.toString());
//Bug 4677074 end
                    if(!removeExecutingTask)
                        insertSorted(task);
                    else
                        removeExecutingTask=false;
                    executingTask=null;
                }
            }
        } // while
    
public java.lang.StringtoString()

        return "[PeriodicEventScheduler: " + sortedList.toString() + "]";