KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > util > scheduler > PeriodicEventScheduler


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 //
25
// Copyright 2001 iPlanet/ Sun Microsystems, Inc. All Rights Reserved.
26
//
27
// Author : darpan
28
// Module : Utils
29
//
30
package com.sun.enterprise.util.scheduler;
31
32 import com.sun.enterprise.util.ApproximateClock;
33 //Bug 4677074 begin
34
import java.util.logging.Logger JavaDoc;
35 import java.util.logging.Level JavaDoc;
36 import com.sun.logging.LogDomains;
37 //Bug 4677074 end
38

39 /**
40 * PeriodicEventScheduler manages tasks of the type PeriodicallyServicable. Such
41 * objects can be added to the manager and the time interval in these objects
42 * defines at what frequency the service() method of these tasks gets invoked by
43 * the manager.<br>
44 * It is critical that the service() operation be as brisk as possible for the
45 * manager to work effectively.<br>
46 * PeriodicEventScheduler is internally set as daemon.
47 * <BR> <I>$Source: /cvs/glassfish/appserv-commons/src/java/com/sun/enterprise/util/scheduler/PeriodicEventScheduler.java,v $</I>
48 * @author $Author: tcfujii $
49 * @version 1.0 $Revision: 1.3 $ $Date: 2005/12/25 04:12:29 $
50 * @see PeriodicallyServicable
51 */

52 public class PeriodicEventScheduler
53     implements Runnable JavaDoc
54 {
55 //Bug 4677074 begin
56
static Logger JavaDoc _logger=LogDomains.getLogger(LogDomains.UTIL_LOGGER);
57 //Bug 4677074 end
58
// TODO: What the scheduler can also do, is to put these tasks at the top of
59
// the worker thread pool task queue, instead of executing the task on itself.
60

61     /** Internal Thread holder */
62     protected Thread JavaDoc _thread;
63     /** Scheduler instance holder */
64     private static PeriodicEventScheduler _instance = null;
65     /** Instance lock */
66     private static Object JavaDoc instanceLock = new Object JavaDoc();
67     /** Sorted task list */
68     protected TimedTaskList sortedList;
69     
70     /** Thread runs while bRun is true (unless shutdown) */
71     protected boolean bRun;
72     /** Debug flag */
73     protected boolean bDebug=false;
74     /** Current time holder */
75     protected transient long counter=0;
76     /** Delay for time approximation */
77     protected long delay_time_approx = 100;
78     /** Approximate clock holder */
79     protected ApproximateClock clock = null;
80
81     static
82     {
83         _instance = new PeriodicEventScheduler();
84     }
85     
86     /**
87     * Method to access the PeriodicEventScheduler singleton.
88     * @return singleton object.
89     */

90     public static PeriodicEventScheduler getInstance()
91     {
92         return _instance;
93     }
94
95     
96     /**
97     * Constructor invoked once for the singleton.
98     */

99     private PeriodicEventScheduler()
100     {
101         super();
102         bRun = true;
103         sortedList = new TimedTaskList();
104         clock = new ApproximateClock (delay_time_approx);
105         counter = getTime();
106         _thread = new Thread JavaDoc (this, "PeriodicEventScheduler");
107         _thread.setDaemon(true);
108         _thread.start();
109     }
110     
111     /**
112     * Get approximate or actual time.
113     * @return long current time.
114     */

115     private long getTime()
116     {
117         return clock.getActualTime(); // TODO : change actual time to perhaps approx time
118
}
119
120     /**
121     * Add a PeriodicallyServicable object to the 'timed task execution queue'.
122     * @param seconds time in seconds after which the task will be invoked for
123     * the first time. <I>Do not confuse with the frequency period which is given
124     * by the getTimeIntervalForService() method on this object.</I>
125     * @param obj object that has to be serviced in timed interval fashion.
126     * @param startingTime start calling service() method in startingTime + frequency time.
127     * @return boolean true on success, false otherwise
128     */

129     public synchronized boolean addTimeRepeatableTask(PeriodicallyServicable obj, int startingTime)
130     {
131         if(startingTime < 0 || obj.getFrequency() < 1)
132         {
133 //Bug 4677074 if(bDebug) System.out.println("PeriodicEventScheduler::addTimeRepeatableTask() rejected task" + obj.toString());
134
//Bug 4677074 begin
135
if(com.sun.enterprise.util.logging.Debug.enabled) _logger.log(Level.FINE,"PeriodicEventScheduler::addTimeRepeatableTask() rejected task" + obj.toString());
136 //Bug 4677074 end
137

138             return false;
139         }
140         boolean bool = sortedList.addTask(obj, startingTime, counter);
141         synchronized(instanceLock)
142         {
143             instanceLock.notify();
144         }
145         return bool;
146     }
147     
148     /**
149     * Remove the servicable object from the task list.
150     * @param obj PeriodicallyServicable object to be removed from the task list.
151     * @return boolean true on success, false otherwise
152     */

153     public synchronized boolean removeTimeRepeatableTask(PeriodicallyServicable obj)
154     {
155         if(executingTask.equals(obj))
156         {
157             removeExecutingTask=true;
158             return true;
159         }
160         else
161             return sortedList.removeTask(obj);
162     }
163     
164     /**
165     * Insert the task object into the task list.
166     * @param taskObj task object to insert.
167     * @return boolean true on success, false otherwise
168     */

169     protected synchronized boolean insertSorted(TaskData taskObj)
170     {
171         return sortedList.insertTask(taskObj);
172     }
173     
174     /** Maintained by the run() method */
175     private PeriodicallyServicable executingTask=null;
176     /** On remove, a check is made if the executingTask is the one to be removed. This is the flag set. */
177     private boolean removeExecutingTask=false;
178     
179     /**
180     * Start running the thread.
181     */

182     public void run()
183     {
184         TaskData task=null;
185
186         while(bRun)
187         {
188             try
189             {
190                 //if(bDebug) System.out.println("---run()" + sortedList.toString() + "---");
191
//Bug 4677074 begin
192
//if(com.sun.enterprise.util.logging.Debug.enabled) _logger.log(Level.FINE,"---run()" + sortedList.toString() + "---");
193
//Bug 4677074 end
194
task = sortedList.getFirstTask();
195                 //if(bDebug) System.out.println("---run()" + sortedList.toString() + "+++");
196
//Bug 4677074 begin
197
//if(com.sun.enterprise.util.logging.Debug.enabled) _logger.log(Level.FINE,"---run()" + sortedList.toString() + "+++");
198
//Bug 4677074 end
199
if(null==task)
200                 {
201                     synchronized(instanceLock)
202                     {
203                         instanceLock.wait();
204                         continue; // fetches a task
205
}
206                 }
207                 
208                 executingTask=task.obj;
209                 
210                 // got the first task
211
counter = getTime();
212                 long sleepingTime = task.abs_execute_time - counter;
213                 if(sleepingTime > 0L)
214                 {
215                     try
216                     {
217 //Bug 4677074 if(bDebug) System.out.println("Current time=" + (int)(counter/1000) + ", Sleeping for " + sleepingTime + " msec.");
218
//Bug 4677074 begin
219
if(com.sun.enterprise.util.logging.Debug.enabled) _logger.log(Level.FINE,"Current time=" + (int)(counter/1000) + ", Sleeping for " + sleepingTime + " msec.");
220 //Bug 4677074 end
221
Thread.sleep( sleepingTime );
222                     }
223                     catch(InterruptedException JavaDoc ieInner)
224                     {
225 //Bug 4677074 if(bDebug) System.out.println("PeriodicEventScheduler::run() > " + ieInner);
226
//Bug 4677074 begin
227
if(com.sun.enterprise.util.logging.Debug.enabled) _logger.log(Level.FINE,"PeriodicEventScheduler::run() > " + ieInner);
228 //Bug 4677074 end
229
}
230                 }else
231                 {
232                     // a decision has to be made immediately if we want to execute
233
// the task even if we missed the right time to execute it
234
if (!task.obj.getExecutionTolerance(Math.abs(sleepingTime)) )
235                     {
236 //Bug 4677074 if(bDebug) System.out.println("Missed scheduling for " + task.obj.toString());
237
//Bug 4677074 begin
238
if(com.sun.enterprise.util.logging.Debug.enabled) _logger.log(Level.FINE,"Missed scheduling for " + task.obj.toString());
239 //Bug 4677074 end
240
continue;
241                     } else
242                     {
243 //Bug 4677074 if(bDebug) System.out.println("Executing after missing scheduling for " + task.obj.toString());
244
//Bug 4677074 begin
245
if(com.sun.enterprise.util.logging.Debug.enabled) _logger.log(Level.FINE,"Executing after missing scheduling for " + task.obj.toString());
246 //Bug 4677074 end
247
}
248                 }
249               
250                 // now we can execute this task in multiple ways, one is on this thread,
251
// other is on other task queues (by putting this task on the front of the Q)
252
task.obj.service();
253                 
254             }catch(InterruptedException JavaDoc ieOuter)
255             {
256 //Bug 4677074 if(bDebug) System.out.println("PeriodicEventScheduler::run() > " + ieOuter);
257
//Bug 4677074 begin
258
if(com.sun.enterprise.util.logging.Debug.enabled) _logger.log(Level.FINE,"PeriodicEventScheduler::run() > " + ieOuter);
259 //Bug 4677074 end
260
}
261             catch(Exception JavaDoc e)
262             {
263                 System.out.println("PeriodicEventScheduler::run() > " + e);
264 //Bug 4677074 begin
265
_logger.log(Level.WARNING,"iplanet_util.generic_exception",e);
266 //Bug 4677074 end
267
}
268             finally
269             {
270                 if (null!=task)
271                 {
272                     counter = getTime();
273                     // now put this task back into the Q
274
task.abs_execute_time = counter;
275                     //if(bDebug) System.out.println("Adding in list " + task.obj.toString());
276
//Bug 4677074 begin
277
//if(com.sun.enterprise.util.logging.Debug.enabled) _logger.log(Level.FINE,"Adding in list " + task.obj.toString());
278
//Bug 4677074 end
279
if(!removeExecutingTask)
280                         insertSorted(task);
281                     else
282                         removeExecutingTask=false;
283                     executingTask=null;
284                 }
285             }
286         } // while
287
}
288     
289     public String JavaDoc toString()
290     {
291         return "[PeriodicEventScheduler: " + sortedList.toString() + "]";
292     }
293 }
294
295
Popular Tags