| <?xml version="1.0"?> |
| <!-- |
| /* |
| * Copyright 2001-2004 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| --> |
| |
| <document> |
| |
| <properties> |
| <title>Turbine Services - Scheduler Service</title> |
| </properties> |
| |
| <body> |
| |
| <section name="Scheduler Service"> |
| |
| <p> |
| The Scheduler is modeled after Unix Cron. The Scheduler runs as a background |
| process that executes timed scheduled tasks independently of HTTP requests. |
| Tasks are stored in the database in the TURBINE_SCHEDULED_JOB table and once |
| entered in the database are loaded automatically when Turbine initializes. |
| </p> |
| |
| <p> |
| For the Scheduler to load classes that extend the ScheduledJob Class, |
| the scheduler needs to be enabled via the TurbineResources.properties |
| file, where the directive services.SchedulerService.enabled needs to be |
| set to true. |
| </p> |
| |
| <p> |
| The Scheduler Service should be accessed in one of two ways. |
| <ul> |
| <li> |
| org.apache.turbine.services.schedule.TurbineScheduler - This class |
| provides static methods to access the scheduler service. This is the |
| preferred method of access from within java code. |
| </li> |
| <li> |
| org.apache.turbine.services.schedule.SchedulerTool - This is a pull |
| tool for providing access to the scheduler service from within a |
| Velocity template. |
| </li> |
| </ul> |
| </p> |
| |
| </section> |
| |
| <section name="Configuration"> |
| |
| <source><![CDATA[ |
| # ------------------------------------------------------------------- |
| # |
| # S E R V I C E S |
| # |
| # ------------------------------------------------------------------- |
| # Classes for Turbine Services should be defined here. |
| # Format: services.[name].classname=[implementing class] |
| # |
| # To specify properties of a service use the following syntax: |
| # service.[name].[property]=[value] |
| |
| services.SchedulerService.classname=org.apache.turbine.services.schedule.TurbineSchedulerService |
| . |
| . |
| . |
| # ------------------------------------------------------------------- |
| # |
| # S C H E D U L E R S E R V I C E |
| # |
| # ------------------------------------------------------------------- |
| |
| # |
| # Set enabled to true to start the scheduler. The scheduler can be |
| # stopped and started after Turbine has been intialized. See the |
| # javadocs for org.apache.turbine.services.schedule.TurbineScheduler |
| # for the methods calls. |
| # |
| # Default = false |
| # |
| |
| services.SchedulerService.enabled=false |
| |
| # Determines if the scheduler service should be initialized early. This |
| # Should always be set to true!!!! |
| |
| services.SchedulerService.earlyInit=true |
| |
| # ------------------------------------------------------------------- |
| # |
| # P U L L S E R V I C E |
| # |
| # ------------------------------------------------------------------- |
| # These are the properties for the Pull Service, the service |
| # that works in conjuction with the Turbine Pull Model API. |
| # ------------------------------------------------------------------- |
| |
| # This is a tool that allows access to the scheduler service. |
| tool.request.scheduler=org.apache.turbine.services.schedule.SchedulerTool |
| |
| ]]></source> |
| |
| <p> |
| Jobs are stored and retrieved from the database using Torque |
| generated objects. The objects are based on the definition |
| stored in <code>scheduler-schema.xml</code>. If you want to |
| add additional fields to track more information about your |
| scheduled tasks, you can modify this file to do so. You will |
| need to rebuild Turbine using MAven after making your modifications. |
| </p> |
| |
| </section> |
| |
| <section name="Usage"> |
| |
| <p> |
| To create an object that takes advantage of the Schedule Service, the task |
| to be executed will need to be embedded in the run() method of an object |
| which extends the ScheduledJob Class. For instance: |
| </p> |
| |
| <source><![CDATA[ |
| |
| package com.mycompany.modules.scheduledjobs; |
| |
| |
| //JDK |
| import java.util.Date; |
| |
| //Turbine |
| import org.apache.turbine.modules.ScheduledJob; |
| import org.apache.turbine.services.schedule.JobEntry; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| |
| |
| public class SimpleScheduledTask extends ScheduledJob |
| { |
| /** Logging */ |
| private static Log log = LogFactory.getLog(SimpleScheduledTask.class); |
| |
| private int taskcount = 0; |
| |
| /** |
| * Constructor |
| */ |
| public SimpleScheduledTask() |
| { |
| //do Task initialization here |
| } |
| |
| |
| /** |
| * Run the Jobentry from the scheduler queue. |
| * From ScheduledJob. |
| * |
| * @param job The job to run. |
| */ |
| public void run( JobEntry job ) throws Exception |
| { |
| log.note("Scheduled job " + job.getJobId() + " : " + |
| "task: " + job.getTask() + |
| " ran @: " + |
| new Date(System.currentTimeMillis()).toString() + |
| " taskcount " + taskcount |
| ); |
| //iterate the task counter |
| taskcount++; |
| } |
| } |
| |
| ]]></source> |
| |
| <p> |
| The SimpleScheduledTask object makes an entry into the turbine.log each |
| time the Task is run by the Schedule Service. The JobEntry object carries the |
| information the Service uses to determine the frequency of the Task. |
| Note that the object is in the com.mycompany.modules. This assumes that the |
| package com.mycompany.modules is in the Turbine module path, which is in the |
| module.packages directive in the TurbineResources.properties. |
| The ScheduledJobLoader object loads the Task upon Turbine initilization also |
| searches for a <i>scheduledjobs</i> package which contains the Task object. |
| </p> |
| |
| <p> |
| Control of the time between, or to, execution of the Task, is controlled by |
| the JobEntry object. The JobEntry serves as a wrapper for the scheduled task. |
| The constructor is as follows: |
| </p> |
| |
| <source><![CDATA[ |
| |
| public JobEntry(int sec, int min, int hour, |
| int wd, int day_mo, String task) |
| throws Exception |
| |
| ]]></source> |
| |
| <p> |
| The granularity of the Task's next execution can be controlled to the level |
| of seconds. In the above constructor, sec represents the seconds with a valid |
| range of 0-59, min represents the minutes with a valid range of 0-59, |
| hour represents the hours with a valid range of 0-23, wd is the day of the |
| week with a valid range of 1-7, day_mo is the day of the month with a valid |
| range of 1-31 and task is the name of the object. The JobEntry constructor |
| allows for the Task to be run at a certain point in time. For example: |
| </p> |
| |
| <source><![CDATA[ |
| |
| JobEntry je = new JobEntry(0,25,-1,-1,-1,"SimpleScheduledTask"); |
| |
| o run every 25 minutes. |
| |
| JobEntry je = new JobEntry(0,0,8,-1,15,"SimpleScheduledTask"); |
| |
| o run at 8:00am on the 15th of the month every month. |
| |
| ]]></source> |
| |
| <p> |
| The Schedule Service will only execute Tasks at Turbine Initialization that |
| are present in the Database. To add a Task to the Database we need to set up |
| an Action class that can be accessed from a template with: |
| </p> |
| |
| <source><![CDATA[ |
| |
| $page.SetTitle("SimpleScheduleTask Starter Page") |
| |
| Set Values for SimpleScheduleTask and then start it for the first time. |
| <br /> |
| |
| <form> |
| <input type="hidden" name="action" value="SchedulerStart" /> |
| <input type="text" name="second" size="20" /> : seconds (0-59)<br /> |
| <input type="text" name="minute" size="20" /> : minutes (0-59)<br /> |
| <input type="text" name="hour" size="20" /> : hours (0-23)<br /> |
| <input type="text" name="weekday" size="20" /> : Day of the Week (1-7)<br /> |
| <input type="text" name="day_of_month" size="20" /> Day of the Month (1-31)<br /> |
| <input type="text" name="task" value="SimpleSchedulerTask" /> : The Task being scheduled. <br /> |
| <input type="text" name="email" /> : Email<br /> |
| </form> |
| |
| ]]></source> |
| |
| <p> |
| and the appropriate Action class: |
| </p> |
| |
| <source><![CDATA[ |
| |
| package com.mycompany.modules.actions; |
| |
| |
| //Turbine |
| import org.apache.turbine.modules.actions.VelocityAction; |
| import org.apache.turbine.services.schedule.JobEntry; |
| import org.apache.turbine.services.schedule.TurbineScheduler; |
| import org.apache.turbine.services.TurbineServices; |
| import org.apache.turbine.util.ParameterParser; |
| import org.apache.turbine.util.RunData; |
| |
| |
| public class AddScheduledTask extends VelocityAction |
| { |
| |
| public void doPerform(RunData data) throws Exception |
| { |
| ParameterParser params = data.getParameters(); |
| |
| int second = params.getInt("second",-1); |
| int minute = params.getInt("minute",-1); |
| int hour = params.getInt("hour",-1); |
| int weekday = params.getInt("weekday",-1); |
| int dom = params.getInt("day_of_month",-1); |
| String task = params.getString("task",""); |
| String email = params.getString("email",""); |
| |
| try |
| { |
| //create a new JobEntry with the time constraints from |
| //the template as the arguments |
| JobEntry je = new JobEntry(second,minute,hour,weekday,dom,task); |
| |
| //set the email for notification |
| je.setEmail(email); |
| |
| //add the job to the queue |
| TurbineScheduler.addJob(je); |
| |
| //set the Message |
| data.setMessage("Task " + task + " added successfully"); |
| } |
| catch (Exception e) |
| { |
| //set the Message |
| data.setMessage("Task " + task + " could not be added!"); |
| } |
| |
| // Note: The template "SchedulerStatus.vm" is not part of Turbine. |
| // It is only here as an example how you might implement this action. |
| setTemplate(data, "SchedulerStatus.vm"); |
| |
| } |
| } |
| |
| ]]></source> |
| |
| <p> |
| The AddScheduledTask action class adds the task to the job queue. The job |
| will also be written to database so that it will be automatically loaded |
| the next time that Turbine starts. |
| </p> |
| <p> |
| The AddScheduledTask action class is really only part of what you would need |
| to implement in order to control the job scheduler from a web interface. It |
| is given as a VERY simple example of how you might implement such functionality. |
| In a more complete implementation, you would have templates to create/edit a scheduled |
| task, display all tasks, and control the scheduler. You would also have action(s) |
| to enable/disable the scheduler and add/update/remove scheduled tasks. |
| </p> |
| <p> |
| The TurbineScheduler class exposes methods that allow the |
| Scheduler process to be monitored and controlled, such as getJob(int oid), |
| removeJob(JobEntry je), updateJob(JobEntry je), listJobs(), startScheduler(), |
| stopScheduler(), and others. See the javadocs on this class for more details. |
| </p> |
| <p> |
| There is also a pull tool for use with the scheduler service (assuming the pull service |
| is enabled). This tool allows you to get basic information from the scheduler service |
| for use in a Velocity template. It provides methods such as getJob(jobId), listJobs(), |
| isEnabled(), and others. See the javadocs for more details. |
| </p> |
| |
| <p> |
| The Scheduler Service uses a seperate thread for each Task it runs to ensure |
| that every job runs on time. It's the programmer's responsibility to ensure |
| that proper precautions to handle issues such as synchronization and long |
| running jobs. As always, check through the relevant Javadocs and source code |
| for more details on the Scheduler Service. |
| </p> |
| |
| </section> |
| |
| </body> |
| </document> |