Commits

Anonymous committed cfb0ddd

Issue number: QUARTZ-249
Added example of using Trigger priorities

git-svn-id: http://svn.opensymphony.com/svn/quartz/trunk@60769f7d36a-ea1c-0410-88ea-9fd03e4c9665

  • Participants
  • Parent commits d46e96d

Comments (0)

Files changed (10)

File docs/wikidocs/Example14.html

+<html>
+    <head>
+        <title>Quartz 1 - 
+        Example14
+         </title>
+	    <link rel="stylesheet" href="styles/site.css" type="text/css" />
+        <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+
+    <body>
+	    <table class="pagecontent" border="0" cellpadding="0" cellspacing="0" width="100%" bgcolor="#ffffff">
+		    <tr>
+			    <td valign="top" class="pagebody">
+				    <h1><a name="Example14-Example14TriggerPriority">Example 14 - Trigger Priorities</a></h1>
+
+<h2><a name="Example14-Overview">Overview</a></h2>
+<p>This example will demonstrate how Trigger priorities can be used to manage firing order for Triggers with the same fire time.</p>
+
+<p>The program will perform the following actions:</p>
+
+<ul>
+	<li>Create a Scheduler with a single worker thread</li>
+	<li>Schedule three Triggers with different priorites that fire the first time at the same time, and a second time at staggered intervals</li>
+	<li>Start up the Quartz Scheduler</li>
+	<li>Wait for 30 seconds to give Quartz a chance to fire the Triggers</li>
+	<li>Shut down the Scheduler</li>
+</ul>
+
+
+<h2><a name="Example14-RunningtheExample">Running the Example</a></h2>
+<p>This example can be executed from the <b>examples/example14</b> directory.   There are two out-of-the-box methods for running this example</p>
+
+<ul>
+	<li><b>example14.sh</b> - A UNIX/Linux shell script</li>
+	<li><b>example14.bat</b> - A Windows Batch file</li>
+</ul>
+
+<h2><a name="Example14-Results">Expected Results</a></h2>
+<p>Each of the three Triggers should fire twice.  Once in order of priority as they all start at the same time, and a second time in order of their staggered firing times.
+You should see something like this in the log or on the console:
+</p>
+
+<div class="code"><div class="codeContent">
+<pre class="code-java">
+[INFO] 15 Aug 12:15:51.345 PM PriorityExampleScheduler_Worker-0 [org.quartz.examples.example14.TriggerEchoJob]
+TRIGGER: Priority10Trigger15SecondRepeat
+
+[INFO] 15 Aug 12:15:51.345 PM PriorityExampleScheduler_Worker-0 [org.quartz.examples.example14.TriggerEchoJob]
+TRIGGER: Priority5Trigger10SecondRepeat
+
+[INFO] 15 Aug 12:15:51.345 PM PriorityExampleScheduler_Worker-0 [org.quartz.examples.example14.TriggerEchoJob]
+TRIGGER: PriorityNeg5Trigger5SecondRepeat
+
+[INFO] 15 Aug 12:15:56.220 PM PriorityExampleScheduler_Worker-0 [org.quartz.examples.example14.TriggerEchoJob]
+TRIGGER: PriorityNeg5Trigger5SecondRepeat
+
+[INFO] 15 Aug 12:16:01.220 PM PriorityExampleScheduler_Worker-0 [org.quartz.examples.example14.TriggerEchoJob]
+TRIGGER: Priority5Trigger10SecondRepeat
+
+[INFO] 15 Aug 12:16:06.220 PM PriorityExampleScheduler_Worker-0 [org.quartz.examples.example14.TriggerEchoJob]
+TRIGGER: Priority10Trigger15SecondRepeat
+</pre>
+</div></div>
+
+<h2><a name="Example14-TheCode">The Code</a></h2>
+<p>The code for this example resides in the package <b>org.quartz.examples.example14</b>.   </p>
+
+<p>The code in this example is made up of the following classes:</p>
+
+<table class='confluenceTable'>
+<tr>
+<th class='confluenceTh'> Class Name </th>
+<th class='confluenceTh'> Description</th>
+</tr>
+<tr>
+<td class='confluenceTd'> PriorityExample </td>
+<td class='confluenceTd'> The main program</td>
+</tr>
+<tr>
+<td class='confluenceTd'> TriggerEchoJob </td>
+<td class='confluenceTd'> A simple job that echos the name if the Trigger that fired it</td>
+</tr>
+</table>
+
+<h3><a name="Example14-TriggerEchoJob">TriggerEchoJob</a></h3>
+<p>TriggerEchoJob is a simple job that implements the <em>Job</em> interface and logs the name of the <em>Trigger</em> that fired it to the log (by default, this will simply go to the screen):</p>
+
+<div class="code"><div class="codeContent">
+<pre class="code-java"><span class="code-keyword">public</span> void execute(JobExecutionContext context) <span class="code-keyword">throws</span> JobExecutionException {
+    LOG.info(<span class="code-quote">"TRIGGER: "</span> + context.getTrigger().getName());
+}</pre>
+</div></div>
+
+<h3><a name="Example14-SimpleExample">PriorityExample</a></h3>
+<p>The program starts by getting an instance of the Scheduler.  This is done by creating a <em>StdSchedulerFactory</em> and then using it to create a scheduler.</p>
+
+<div class="code"><div class="codeContent">
+<pre class="code-java">
+SchedulerFactory sf = <span class="code-keyword">new</span> StdSchedulerFactory(
+    <span class="code-quote">"org/quartz/examples/example14/quartz_priority.properties"</span>);
+Scheduler sched = sf.getScheduler();
+</div></div>
+
+<p>We pass a specific Quartz properties file to configure our new Scheduler instance.  
+These properties will create a simple, RAM-based scheduler with only one worker thread 
+so we can see priorities act as the tie breaker when Triggers compete for the single thread, <em>quartz_priority.properties</em>:</p>
+<div class="code"><div class="codeContent">
+<pre class="code-java">
+org.quartz.scheduler.instanceName=PriorityExampleScheduler
+
+<span class="code-comment"># Set thread count to 1 to force Triggers scheduled for the same time to 
+# to be ordered by priority.</span>
+org.quartz.threadPool.threadCount=1
+org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
+
+org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore
+</pre>
+</div></div>
+
+<p>The TriggerEchoJob is defined as a Job to Quartz using the <em>JobDetail</em> class.  It passes <b>null</b> for its group, so it will use the default group:</p>
+<div class="code"><div class="codeContent">
+<pre class="code-java">JobDetail job = <span class="code-keyword">new</span> JobDetail(<span class="code-quote">"TriggerEchoJob"</span>, <span class="code-keyword">null</span>, TriggerEchoJob.class);</pre>
+</div></div>
+
+<p>We create three <em>SimpleTrigger</em>s that will all fire the first time five seconds from now but with different priorities, and then fire a second time at staggered five second intervals:</p>
+<div class="code"><div class="codeContent">
+<pre class="code-java">
+<span class="code-comment">// Calculate the start time of all triggers as 5 seconds from now</span>
+Calendar startTime = Calendar.getInstance();
+startTime.add(Calendar.SECOND, 5);
+        
+<span class="code-comment">// First trigger has priority of -5, and will repeat after 5 seconds</span>
+SimpleTrigger trigger1 = 
+    <span class="code-keyword">new</span> SimpleTrigger(<span class="code-quote">"PriorityNeg5Trigger5SecondRepeat"</span>, null, startTime.getTime(), null, 1, 5L * 1000L);
+trigger1.setPriority(-5);
+trigger1.setJobName(<span class="code-quote">"TriggerEchoJob"</span>);
+
+<span class="code-comment">// Second trigger has default priority of 5, and will repeat after 10 seconds</span>
+SimpleTrigger trigger2 = 
+    <span class="code-keyword">new</span> SimpleTrigger(<span class="code-quote">"Priority5Trigger10SecondRepeat"</span>, null, startTime.getTime(), null, 1, 10L * 1000L);
+trigger2.setJobName(<span class="code-quote">"TriggerEchoJob"</span>);
+        
+<span class="code-comment">// Third trigger has priority 10, and will repeat after 15 seconds</span>
+SimpleTrigger trigger3 = 
+    <span class="code-keyword">new</span> SimpleTrigger(<span class="code-quote">"Priority10Trigger15SecondRepeat"</span>, null, startTime.getTime(), null, 1, 15L * 1000L);
+trigger3.setPriority(10);
+trigger3.setJobName(<span class="code-quote">"TriggerEchoJob"</span>);
+</pre>
+</div></div>
+
+<p>We now associate the three Triggers with our Job in the scheduler.  The first time we need to also add the job itself to the scheduler:</p>
+<div class="code"><div class="codeContent">
+<pre class="code-java">
+<span class="code-comment">// Tell quartz to schedule the job using our trigger</span>
+sched.scheduleJob(job, trigger1);
+sched.scheduleJob(trigger2);
+sched.scheduleJob(trigger3);
+</pre>
+</div></div>
+
+<p>At this point, the triggers have been scheduled to run.  However, the scheduler is not yet running.   So, we must tell the scheduler to start up!</p>
+<div class="code"><div class="codeContent">
+<pre class="code-java">sched.start();</pre>
+</div></div>
+
+<p>To let the program have an opportunity to run the job, we then sleep for 30 seconds.  The scheduler is running in the background and should fire off the job six times during those 30 seonds.</p>
+<div class="code"><div class="codeContent">
+<pre class="code-java"><span class="code-object">Thread</span>.sleep(30L * 1000L);</pre>
+</div></div>
+
+<p>Finally, we will gracefully shutdown the scheduler:</p>
+<div class="code"><div class="codeContent">
+<pre class="code-java">sched.shutdown(<span class="code-keyword">true</span>);</pre>
+</div></div>
+<p>Note:  passing <em>true</em> into the <em>shutdown</em> message tells the Quartz Scheduler to wait until all jobs have completed running before returning from the method call.</p>
+
+
+                    			    </td>
+		    </tr>
+	    </table>
+    </body>
+</html>

File docs/wikidocs/Examples Overview.html

 <td class='confluenceTd'> Clustered Quartz </td>
 <td class='confluenceTd'> Demonstrates how Quartz can be used in a clustered environment and how Quartz can use the database to persist scheduling information</td>
 </tr>
+<tr>
+<td class='confluenceTd'> <a href="Example14.html" title="Example14">Example 14</a> </td>
+<td class='confluenceTd'> Trigger Priorites </td>
+<td class='confluenceTd'> Demonstrate how Trigger priorities can be used to manage firing order for Triggers with the same fire time</td>
+</tr>
 </table>
 
                     			    </td>

File examples/example14/example14.bat

+@echo off
+
+rem Set Quartz to the base directory of the Quartz Distribution
+@SET QUARTZ=..\..
+
+@rem setup the class path...
+CALL ..\bin\buildcp.bat
+SET QUARTZ_CP=%TMP_CP%
+
+rem !!!!!!! Please read important information. !!!!!!
+rem If "java" is not in your path, please set the path 
+rem for Java 2 Runtime Environment in the path variable below
+rem for example :
+rem @SET PATH=D:\jdk1.3.1;%PATH%
+rem 
+
+
+rem Set LOG4J props if you are interested in setting up
+rem a configuraiton file for log4j logging
+rem @SET LOG4J_PROPS="-Dlog4j.configuration=log4j.properties"
+
+"java" -cp "%QUARTZ_CP%" %LOG4J_PROPS% org.quartz.examples.example14.PriorityExample

File examples/example14/example14.sh

+#!/bin/sh
+
+# Change this to your JDK installation root
+#
+#JAVA_HOME=/usr/java/j2sdk1.4.0_01
+
+JRE=$JAVA_HOME/jre
+JAVA=$JRE/bin/java
+
+. ${QUARTZ}/examples/bin/buildcp.sh
+
+# Uncomment the following line if you would like to set log4j
+# logging properties
+#
+#LOGGING_PROPS="-Dlog4j.configuration=log4j.properties"
+
+$JAVA -classpath $QUARTZ_CP $LOGGING_PROPS org.quartz.examples.example14.PriorityExample
+

File examples/example14/log4j.xml

+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+
+  <appender name="default" class="org.apache.log4j.ConsoleAppender">
+    <param name="target" value="System.out"/>
+    <layout class="org.apache.log4j.PatternLayout">
+      <param name="ConversionPattern" value="[%p] %d{dd MMM hh:mm:ss.SSS aa} %t [%c]%n%m%n%n"/>
+    </layout>
+  </appender>
+
+
+ <logger name="org.quartz">
+   <level value="debug" />
+ </logger>
+
+  <root>
+    <level value="debug" />
+    <appender-ref ref="default" />
+  </root>
+
+  
+</log4j:configuration>

File examples/example14/priority_readme.txt

+Example 14
+==========
+
+Overview:
+=========
+This example will demonstrate how Trigger priorities can be
+used to manage firing order for Triggers with the same fire time.
+
+Running the Example:
+====================
+1. Windows users - Modify the example1.bat file (if necessary) 
+to set your JAVA_HOME.  Run example1.bat
+
+2. UNIX/Linux users - Modify the example1.sh file (if necessary)
+to set your JAVA_HOME.  Execute example1.sh
+
+
+Configuration Files:
+====================
+1.  You can decide to specify a log4j.properties file to
+control logging output (optional)

File examples/examples_guide.txt

 
 Welcome to the Quartz Examples directory.  
 
-This directory contains 13 examples that show you how to use various
+This directory contains 14 examples that show you how to use various
 features of Quartz.   Each example is located in its own subdirectory. 
 Every example can be run using Windows .bat files or Linux/UNIX .sh files.  
 
 example11 - Loading Up Quartz with Many Jobs
 example12 - Remoting with Quartz using RMI
 example13 - Clustering Quartz and JDBC Job Stores
+example14 - Quartz Trigger Priorities

File examples/src/java/org/quartz/examples/example14/PriorityExample.java

+/* 
+ * Copyright 2006 OpenSymphony 
+ * 
+ * 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.
+ * 
+ */
+package org.quartz.examples.example14;
+
+import java.util.Calendar;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.quartz.JobDetail;
+import org.quartz.Scheduler;
+import org.quartz.SchedulerFactory;
+import org.quartz.SimpleTrigger;
+import org.quartz.impl.StdSchedulerFactory;
+
+/**
+ * This Example will demonstrate how Triggers are ordered by priority.
+ */
+public class PriorityExample {
+    
+    public void run() throws Exception {
+        Log log = LogFactory.getLog(PriorityExample.class);
+
+        log.info("------- Initializing ----------------------");
+
+        // First we must get a reference to a scheduler
+        SchedulerFactory sf = new StdSchedulerFactory(
+                "org/quartz/examples/example14/quartz_priority.properties");
+        Scheduler sched = sf.getScheduler();
+
+        log.info("------- Initialization Complete -----------");
+
+        log.info("------- Scheduling Jobs -------------------");
+
+        JobDetail job = new JobDetail("TriggerEchoJob", null, TriggerEchoJob.class);
+
+        // All three triggers will fire their first time at the same time, 
+        // ordered by their priority, and then repeat once, firing in a 
+        // staggered order that therefore ignores priority.
+        //
+        // We should see the following firing order:
+        // 1. Priority10Trigger15SecondRepeat
+        // 2. Priority5Trigger10SecondRepeat
+        // 3. PriorityNeg5Trigger5SecondRepeat
+        // 4. PriorityNeg5Trigger5SecondRepeat
+        // 5. Priority5Trigger10SecondRepeat
+        // 6. Priority10Trigger15SecondRepeat
+        
+        // Calculate the start time of all triggers as 5 seconds from now
+        Calendar startTime = Calendar.getInstance();
+        startTime.add(Calendar.SECOND, 5);
+        
+        // First trigger has priority of -5, and will repeat after 5 seconds
+        SimpleTrigger trigger1 = 
+            new SimpleTrigger("PriorityNeg5Trigger5SecondRepeat", null, startTime.getTime(), null, 1, 5L * 1000L);
+        trigger1.setPriority(-5);
+        trigger1.setJobName("TriggerEchoJob");
+
+        // Second trigger has default priority of 5, and will repeat after 10 seconds
+        SimpleTrigger trigger2 = 
+            new SimpleTrigger("Priority5Trigger10SecondRepeat", null, startTime.getTime(), null, 1, 10L * 1000L);
+        trigger2.setJobName("TriggerEchoJob");
+        
+        // Third trigger has priority 10, and will repeat after 15 seconds
+        SimpleTrigger trigger3 = 
+            new SimpleTrigger("Priority10Trigger15SecondRepeat", null, startTime.getTime(), null, 1, 15L * 1000L);
+        trigger3.setPriority(10);
+        trigger3.setJobName("TriggerEchoJob");
+        
+        // Tell quartz to schedule the job using our trigger
+        sched.scheduleJob(job, trigger1);
+        sched.scheduleJob(trigger2);
+        sched.scheduleJob(trigger3);
+
+        // Start up the scheduler (nothing can actually run until the 
+        // scheduler has been started)
+        sched.start();
+        log.info("------- Started Scheduler -----------------");
+
+        // wait long enough so that the scheduler as an opportunity to 
+        // fire the triggers
+        log.info("------- Waiting 30 seconds... -------------");
+        try {
+            Thread.sleep(30L * 1000L); 
+            // executing...
+        } catch (Exception e) {
+        }
+
+        // shut down the scheduler
+        log.info("------- Shutting Down ---------------------");
+        sched.shutdown(true);
+        log.info("------- Shutdown Complete -----------------");
+    }
+
+    public static void main(String[] args) throws Exception {
+        PriorityExample example = new PriorityExample();
+        example.run();
+    }
+}

File examples/src/java/org/quartz/examples/example14/TriggerEchoJob.java

+/* 
+ * Copyright 2006 OpenSymphony 
+ * 
+ * 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.
+ * 
+ */
+package org.quartz.examples.example14;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+
+/**
+ * This is just a simple job that echos the name of the Trigger
+ * that fired it.
+ */
+public class TriggerEchoJob implements Job {
+
+    private static final Log LOG = LogFactory.getLog(TriggerEchoJob.class);
+
+    /**
+     * Empty constructor for job initilization
+     *
+     * <p>
+     * Quartz requires a public empty constructor so that the
+     * scheduler can instantiate the class whenever it needs.
+     * </p>
+     */
+    public TriggerEchoJob() {
+    }
+
+    /**
+     * <p>
+     * Called by the <code>{@link org.quartz.Scheduler}</code> when a
+     * <code>{@link org.quartz.Trigger}</code> fires that is associated with
+     * the <code>Job</code>.
+     * </p>
+     * 
+     * @throws JobExecutionException
+     *             if there is an exception while executing the job.
+     */
+    public void execute(JobExecutionContext context)
+        throws JobExecutionException {
+        LOG.info("TRIGGER: " + context.getTrigger().getName());
+    }
+
+}

File examples/src/java/org/quartz/examples/example14/quartz_priority.properties

+org.quartz.scheduler.instanceName=PriorityExampleScheduler
+
+# Set thread count to 1 to force Triggers scheduled for the same time to 
+# to be ordered by priority.
+org.quartz.threadPool.threadCount=1
+org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
+
+org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore