View Javadoc
1 package org.apache.turbine.services.schedule; 2 3 /* ==================================================================== 4 * The Apache Software License, Version 1.1 5 * 6 * Copyright (c) 2001 The Apache Software Foundation. All rights 7 * reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. The end-user documentation included with the redistribution, 22 * if any, must include the following acknowledgment: 23 * "This product includes software developed by the 24 * Apache Software Foundation (http://www.apache.org/)." 25 * Alternately, this acknowledgment may appear in the software itself, 26 * if and wherever such third-party acknowledgments normally appear. 27 * 28 * 4. The names "Apache" and "Apache Software Foundation" and 29 * "Apache Turbine" must not be used to endorse or promote products 30 * derived from this software without prior written permission. For 31 * written permission, please contact apache@apache.org. 32 * 33 * 5. Products derived from this software may not be called "Apache", 34 * "Apache Turbine", nor may "Apache" appear in their name, without 35 * prior written permission of the Apache Software Foundation. 36 * 37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 * ==================================================================== 50 * 51 * This software consists of voluntary contributions made by many 52 * individuals on behalf of the Apache Software Foundation. For more 53 * information on the Apache Software Foundation, please see 54 * <http://www.apache.org/>;. 55 */ 56 57 import java.util.List; 58 import java.util.Vector; 59 import javax.servlet.ServletConfig; 60 import org.apache.torque.util.Criteria; 61 import org.apache.turbine.services.InitializationException; 62 import org.apache.turbine.services.TurbineBaseService; 63 import org.apache.turbine.services.resources.TurbineResources; 64 65 /*** 66 * Service for a cron like scheduler. 67 * 68 * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a> 69 * @version $Id: TurbineSchedulerService.java,v 1.3 2002/07/11 16:53:24 mpoeschl Exp $ 70 */ 71 public class TurbineSchedulerService 72 extends TurbineBaseService 73 implements ScheduleService 74 { 75 /*** 76 * The queue. 77 */ 78 protected JobQueue scheduleQueue = null; 79 80 /*** 81 * The main loop for starting jobs. 82 */ 83 protected MainLoop mainLoop; 84 85 /*** 86 * The thread used to process commands. 87 */ 88 protected Thread thread; 89 90 /*** 91 * Creates a new instance. 92 */ 93 public TurbineSchedulerService() 94 { 95 mainLoop = null; 96 thread = null; 97 } 98 99 /*** 100 * Called the first time the Service is used.<br> 101 * 102 * Load all the jobs from cold storage. Add jobs to the queue 103 * (sorted in ascending order by runtime) and start the scheduler 104 * thread. 105 * 106 * @param config A ServletConfig. 107 */ 108 public void init(ServletConfig config) 109 throws InitializationException 110 { 111 try 112 { 113 // START SCHEDULER HERE 114 if ( TurbineResources.getBoolean("scheduler.enabled", false) ) 115 { 116 scheduleQueue = new JobQueue(); 117 mainLoop = new MainLoop(); 118 119 // Load all from cold storage. 120 List jobs = JobEntryPeer.doSelect(new Criteria()); 121 122 if ( jobs != null && jobs.size() > 0 ) 123 { 124 scheduleQueue.batchLoad(jobs); 125 restart(); 126 } 127 128 setInit(true); 129 } 130 else 131 { 132 org.apache.turbine.util.Log.info ("TurbineSchedulerService was not started " + 133 "because scheduler.enabled is not 'true' in the TurbineResources.properties file."); 134 } 135 } 136 catch (Exception e) 137 { 138 throw new InitializationException("TurbineSchedulerService failed to initialize", e); 139 } 140 } 141 142 /*** 143 * Shutdowns the service. 144 * 145 * This methods interrupts the housekeeping thread. 146 */ 147 public void shutdown() 148 { 149 if(getThread() != null) 150 { 151 getThread().interrupt(); 152 } 153 } 154 155 /*** 156 * Get a specific Job from Storage. 157 * 158 * @param oid The int id for the job. 159 * @return A JobEntry. 160 * @exception Exception, a generic exception. 161 */ 162 public JobEntry getJob(int oid) 163 throws Exception 164 { 165 JobEntry je = JobEntryPeer.getJob(oid); 166 return scheduleQueue.getJob(je); 167 } 168 169 /*** 170 * Add a new job to the queue. 171 * 172 * @param je A JobEntry with the job to add. 173 * @exception Exception, a generic exception. 174 */ 175 public void addJob(JobEntry je) 176 throws Exception 177 { 178 try 179 { 180 // Save to DB. 181 je.save(); 182 } 183 catch(Exception e) 184 { 185 // Log problems. 186 org.apache.turbine.util.Log.error ( "Problem saving new Scheduled Job: " + e); 187 } 188 // Add to the queue. 189 scheduleQueue.add(je); 190 restart(); 191 } 192 193 /*** 194 * Remove a job from the queue. 195 * 196 * @param je A JobEntry with the job to remove. 197 * @exception Exception, a generic exception. 198 */ 199 public void removeJob(JobEntry je) 200 throws Exception 201 { 202 // First remove from DB. 203 try 204 { 205 Criteria c = new Criteria() 206 .add(JobEntryPeer.OID, je.getPrimaryKey()); 207 208 JobEntryPeer.doDelete(c); 209 } 210 catch(Exception ouch) 211 { 212 // Log problem. 213 org.apache.turbine.util.Log.error ( "Problem removing Scheduled Job: " + ouch); 214 } 215 216 // Remove from the queue. 217 scheduleQueue.remove(je); 218 restart(); 219 } 220 221 /*** 222 * Modify a Job. 223 * 224 * @param je A JobEntry with the job to modify 225 * @exception Exception, a generic exception. 226 */ 227 public void updateJob(JobEntry je) 228 throws Exception 229 { 230 try 231 { 232 je.calcRunTime(); 233 je.save(); 234 } 235 catch(Exception e) 236 { 237 // Log problems. 238 org.apache.turbine.util.Log.error ( "Problem updating Scheduled Job: " + e); 239 } 240 // Update the queue. 241 scheduleQueue.modify(je); 242 restart(); 243 } 244 245 /*** 246 * List jobs in the queue. This is used by the scheduler UI. 247 * 248 * @return A Vector of jobs. 249 */ 250 public Vector listJobs() 251 { 252 return scheduleQueue.list(); 253 } 254 255 /*** 256 * Return the thread being used to process commands, or null if 257 * there is no such thread. You can use this to invoke any 258 * special methods on the thread, for example, to interrupt it. 259 * 260 * @return A Thread. 261 */ 262 public synchronized Thread getThread() 263 { 264 return thread; 265 } 266 267 /*** 268 * Set thread to null to indicate termination. 269 */ 270 private synchronized void clearThread() 271 { 272 thread = null; 273 } 274 275 /*** 276 * Start (or restart) a thread to process commands, or wake up an 277 * existing thread if one is already running. This method can be 278 * invoked if the background thread crashed due to an 279 * unrecoverable exception in an executed command. 280 */ 281 public synchronized void restart() 282 { 283 if (thread == null) 284 { 285 // Create the the housekeeping thread of the scheduler. It will wait 286 // for the time when the next task needs to be started, and then 287 // launch a worker thread to execute the task. 288 thread = new Thread(mainLoop, ScheduleService.SERVICE_NAME); 289 // Indicate that this is a system thread. JVM will quit only when there 290 // are no more active user threads. Settings threads spawned internally 291 // by Turbine as daemons allows commandline applications using Turbine 292 // to terminate in an orderly manner. 293 thread.setDaemon(true); 294 thread.start(); 295 } 296 else 297 { 298 notify(); 299 } 300 } 301 302 /*** 303 * Return the next Job to execute, or null if thread is 304 * interrupted. 305 * 306 * @return A JobEntry. 307 * @exception Exception, a generic exception. 308 */ 309 private synchronized JobEntry nextJob() 310 throws Exception 311 { 312 try 313 { 314 while ( !Thread.interrupted() ) 315 { 316 // Grab the next job off the queue. 317 JobEntry je = scheduleQueue.getNext(); 318 319 if (je == null) 320 { 321 // Queue must be empty. Wait on it. 322 wait(); 323 } 324 else 325 { 326 long now = System.currentTimeMillis(); 327 long when = je.getNextRuntime(); 328 329 if ( when > now ) 330 { 331 // Wait till next runtime. 332 wait(when - now); 333 } 334 else 335 { 336 // Update the next runtime for the job. 337 scheduleQueue.updateQueue(je); 338 // Return the job to run it. 339 return je; 340 } 341 } 342 } 343 } 344 catch (InterruptedException ex) 345 { 346 } 347 348 // On interrupt. 349 return null; 350 } 351 352 /*** 353 * Inner class. This is isolated in its own Runnable class just 354 * so that the main class need not implement Runnable, which would 355 * allow others to directly invoke run, which is not supported. 356 */ 357 protected class MainLoop 358 implements Runnable 359 { 360 /*** 361 * Method to run the class. 362 */ 363 public void run() 364 { 365 try 366 { 367 for(;;) 368 { 369 JobEntry je = nextJob(); 370 if ( je != null ) 371 { 372 // Start the thread to run the job. 373 Runnable wt = new WorkerThread(je); 374 Thread helper = new Thread(wt); 375 helper.start(); 376 } 377 else 378 { 379 break; 380 } 381 } 382 } 383 catch(Exception e) 384 { 385 // Log error. 386 org.apache.turbine.util.Log.error ( "Error running a Scheduled Job: " + e); 387 } 388 finally 389 { 390 clearThread(); 391 } 392 } 393 } 394 }

This page was automatically generated by Maven