Showing posts with label Scheduling. Show all posts
Showing posts with label Scheduling. Show all posts

Sunday, January 2, 2011

Spring 3 - Quartz Scheduling

In this tutorial we will explore Spring 3's task scheduling support using the Quartz Scheduler. Spring also provides scheduling support using annotations (see Spring 3 - Task Scheduling via Annotations: @Scheduled, @Async), and via XML configuration (see Spring 3 - Task Scheduling via "scheduled-tasks" Element). We will build our application on top of a simple Spring MVC 3 application. Although MVC is not required, I would like to show how easy it is to integrate.

Why do we need scheduling?
Scheduling is needed if you want to automate the repetition of a task at specific intervals or particular date. You could of course manually watch the time and execute your task, albeit an inefficient task. Who wants to watch the computer every 3 seconds just to hit the Enter key? No one.

The work
We want to run the following sample class at specific intervals:

The task that we're interested is inside the work() method. This example is based on Mark Fisher's example at Task Scheduling Simplifications in Spring 3.0. This method retrieves the thread name, prints the starting and beginning of the method, simulates work by putting the thread in sleep for 10 seconds.

To schedule this using Quartz, we'll do it in two ways via the JobDetailBean and via the MethodInvokingJobDetailFactoryBean.

MethodInvokingJobDetailFactoryBean
The MethodInvokingJobDetailFactoryBean is the simpler of the two, albeit simple options. So we'll start with that.

Using the MethodInvokingJobDetailFactoryBean
Often you just need to invoke a method on a specific object. Using the MethodInvokingJobDetailFactoryBean you can do exactly this.... Using the MethodInvokingJobDetailFactoryBean, you don't need to create one-line jobs that just invoke a method, and you only need to create the actual business object and wire up the detail object.

Source: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/scheduling.html
Let's examine an actual example. We'll create a new class SyncWorker that implements a Worker interface.

Worker

SyncWorker

This worker is synchronous which means if we have to call this worker 10 times, it will block the other workers. They cannot start immediately until the first one is finished. If you like to see an example of asynchronous scheduling, please see Spring 3 - Task Scheduling via Annotations: @Scheduled, @Async

To run this using the MethodInvokingJobDetailFactoryBean, we need to declare it in an XML configuration:

quartz-job.xml

We have declared our SyncWorker as a simple bean:

Then we made a reference to our worker inside a MethodInvokingJobDetailFactoryBean. On the targetMethod property, we assign the method name work() that needs to be scheduled.

In order for this to be triggered, we need a Trigger.

This trigger runs every 10 seconds, with a starting delay of 10 seconds as well.
In order for this trigger to be managed, we need a Scheduler
The SchedulerFactoryBean purpose is to schedule the actual jobs assigned in the triggers. You may wonder why we need to have a scheduler, a trigger, and a job just to schedule a single task in Quartz?
Quartz uses Trigger, Job and JobDetail objects to realize scheduling of all kinds of jobs. For the basic concepts behind Quartz, have a look at http://www.opensymphony.com/quartz. For convenience purposes, Spring offers a couple of classes that simplify the usage of Quartz within Spring-based applications. Source: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/scheduling.html
Let's run the application and see the output on the logs:
Notice how our worker is executed. It runs synchronously as expected. The numbers in Worker-1, Worker-2, and etc represents the thread ppol. Our max Worker is 10, so we have a pool size of 10. To modify this value, add the following quartzProperties in the SchedulerFactoryBean:

JobDetailBean
Let's explore another way of scheduling using Quartz. We'll use the JobDetailBean.

What is a JobDetailBean
Convenience subclass of Quartz's JobDetail class, making bean-style usage easier.

JobDetail itself is already a JavaBean but lacks sensible defaults. This class uses the Spring bean name as job name, and the Quartz default group ("DEFAULT") as job group if not specified.

Source: http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/scheduling/quartz/JobDetailBean.html
Let's examine an actual example. We'll create a custom class CustomJob that extends QuartzJobBean and implements StatefulJob

CustomJob

Notice our worker is a normal private field. We have assigned a setter method for this worker.

This is required so that Spring can inject the value from the XML configuration. Our worker is executed inside the executeInternal() method:

You can access various details of your job via the JobExecutionContext.

To activate our CustomJob, we need to enable it in the XML configuration.

quartz-job.xml

The configuration is similar with our first example using MethodInvokingJobDetailFactoryBean. The main difference here is we're using aJobDetailBean

We're also using a CronTrigger. Nonetheless, the idea is similar with our initial example.

Let's run our application and see the output:

Same result. We just have more logs because of the CustomJob.

That's it. We've added scheduling support using the Quartz Scheduler. We've used two support beans to realize our goal. Feel free to modify the MVC app to fit your needs. You might wanna try integrating a web service with scheduling and show the results via MVC. The welcome page is accesible at
http://localhost:8080/spring-mvc-quartz-scheduling/krams/main/welcome
The best way to learn further is to try the actual application.

Download the project
You can access the project site at Google's Project Hosting at http://code.google.com/p/spring-mvc-scheduling/

You can download the project as a Maven build. Look for the spring-mvc-quartz-scheduling.zip in the Download sections.

You can run the project directly using an embedded server via Maven.
For Tomcat: mvn tomcat:run
For Jetty: mvn jetty:run

If you need to know more about Task Scheduling in Spring 3.0, please visit the following links:

StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Spring 3 - Quartz Scheduling ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share

Spring 3 - Task Scheduling via Annotations: @Scheduled, @Async

In this tutorial we will explore Spring 3's task scheduling support using annotations. We will be using @Scheduled and @Async annotations. Spring also provides scheduling support using the Quartz Scheduler, and via XML configuration (see Spring 3 - Task Scheduling via "scheduled-tasks" Element). We will build our application on top of a simple Spring MVC 3 application. Although MVC is not required, I would like to show how easy it is to integrate.

Why do we need scheduling?
Scheduling is needed if you want to automate the repetition of a task at specific intervals or particular date. You could of course manually watch the time and execute your task, albeit an inefficient task. Who wants to watch the computer every 3 seconds just to hit the Enter key? No one.

The work
We want to run the following sample class at specific intervals:

The task that we're interested is inside the work() method. This example is based on Mark Fisher's example at Task Scheduling Simplifications in Spring 3.0. This method retrieves the thread name, prints the starting and beginning of the method, simulates work by putting the thread in sleep for 10 seconds.

To schedule this using Spring's annotation support, we'll use the @Scheduled annotation.

The @Scheduled Annotation
Spring 3.0 also adds annotation support for both task scheduling and asynchronous method execution.... The @Scheduled annotation can be added to a method along with trigger metadata.

Source: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/scheduling.html
To enable this annotation we need to add the annotation-driven element:

You also need to add the component-scan element. We didn't enable it here since it's already added in the applicationContext.xml (see the accompanying source code at the end of this tutorial)

Let's examine an actual example. We'll create a new class SyncWorker that implements a Worker interface.

Worker

SyncWorker

This worker is synchronous which means if we have to call this worker 10 times, it will block the other workers. They cannot start immediately until the first one is finished. We didn't do anything to make this implementation synchronous. It's the default.

The class that calls this SyncWorker is a scheduler service.
Notice the @Scheduled annotation in the doSchedule() method. This tells Spring to mark this method for task scheduling. Inside the @Scheduled, there's a metadata that describes when the method should be triggered. The following metadata all have the same value (5 seconds) but they are interpreted differently:
fixedDelay=5000
fixedRate=5000 
cron="*/5 * * * * ?"
fixedDelay: An interval-based trigger where the interval is measured from the completion time of the previous task. fixedRate: An interval-based trigger where the interval is measured from the start time of the previous task. cron: A cron-based trigger Running the application gives us the following logs:
Notice how the tasks are run sequentially every 5 seconds.

What if we want to run the workers asynchronously, meaning we don't want to wait for worker 1 to finish before we start worker 2, or worker 3, and so forth? There are valid reasons like efficient use of physical resources and time.

To make a worker asychronous, we add the @Async annotation in the method that needs to be asychronous.

The @Async Annotation
The @Async annotation can be provided on a method so that invocation of that method will occur asynchronously. In other words, the caller will return immediately upon invocation and the actual execution of the method will occur in a task that has been submitted to a Spring TaskExecutor.

Source: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/scheduling.html
To enable this annotation we use the same annotation-driven element.

Let's examine an actual example. We'll create a new class AsyncWorker that implements the Worker interface earlier.

AsyncWorker

This worker is asychronous. The caller (the scheduler service) will return immediately upon invocation.

The class that calls this AsyncWorker is the same scheduler service we had earlier. We
just need to change the value of @Qualifier

Same implementation, except for the asyncWorker reference. It's unbelievably easy.

Running the application gives us the following logs:

Notice how the tasks are run asynchronously.

One final note. Let's examine the XML file that contains the annotation-driven element:

Notice I have added two attributes in the annotation-driven element: executor and scheduler. Both are references to the beans declared at the bottom of the file. The ids of these beans become the default thread name prefixes. See below (taskScheduler-1 and executorWithPoolSizeRange-1):


That's it. We've added scheduling support using the @Scheduled annotation, and asychronous support using the @Async annotation. To see the output, please check the logs. Feel free to modify the MVC app to fit your needs. You might wanna try integrating a web service with scheduling and show the results via MVC. The welcome page is accesible at
http://localhost:8080/spring-mvc-task-scheduling-annotation/krams/main/welcome
The best way to learn further is to try the actual application.

Download the project
You can access the project site at Google's Project Hosting at http://code.google.com/p/spring-mvc-scheduling/

You can download the project as a Maven build. Look for the spring-mvc-task-scheduling-annotation.zip in the Download sections.

You can run the project directly using an embedded server via Maven.
For Tomcat: mvn tomcat:run
For Jetty: mvn jetty:run

If you need to know more about Task Scheduling in Spring 3.0, please visit the following links:

StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Spring 3 - Task Scheduling via Annotations: @Scheduled, @Async ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share

Spring 3 - Task Scheduling via "scheduled-tasks" Element

In this tutorial we will explore Spring 3's task scheduling support based on the scheduled-tasks element. Spring also provides scheduling support using the Quartz Scheduler. However, we will focus solely on Spring 3's built-in scheduler for this tutorial. We will build our application on top of a simple Spring MVC 3 application. Although MVC is not required, I would like to show how easy it is to integrate.

Why do we need scheduling?
Scheduling is needed if you want to automate the repetition of a task at specific intervals or particular date. You could of course manually watch the time and execute your task, albeit an inefficient task. Who wants to watch the computer every 3 seconds just to hit the Enter key? No one.

The work
We want to run the following sample class at specific intervals:

The task that we're interested is inside the work() method. This example is based on Mark Fisher's example at Task Scheduling Simplifications in Spring 3.0. This method retrieves the thread name, prints the starting and beginning of the method, simulates work by putting the thread in sleep for 10 seconds.

To schedule this using Spring's scheduling support via XML, we'll use the tag scheduled-tasks element.

The 'scheduled-tasks' element
The most powerful feature of Spring's task namespace is the support for configuring tasks to be scheduled within a Spring Application Context. This follows an approach similar to other "method-invokers" in Spring, such as that provided by the JMS namespace for configuring Message-driven POJOs. Basically a "ref" attribute can point to any Spring-managed object, and the "method" attribute provides the name of a method to be invoked on that object.

Source: Spring Framework 3 Reference, Chapter 25. Task Execution and Scheduling
We've prepared a separate XML file to contain all configurations relating to scheduling.

spring-scheduler.xml

This config is actually shorter if we remove the comments.

Notice we declared three references to our tasks inside the scheduled-tasks element:

Each has task has their own triggers (the schedule when they will be executed). These tasks are managed by the taskScheduler

The id is used as the default thread name prefix. You can also configure the pool size.

We've declared three beans as tasks:

These are simple POJOs with no dependency over Spring's scheduling. This mean we can easily add scheduling to existing beans.

Here are the classes for these beans:

FixedDelayWorker

FixedRateWorker

FixedDelayWorker

Worker

Running the application, the logs show the following output:

Notice how the FixedRateWorker is executed multiple times. This doesn't look right. We've scheduled it using the fixed-rate attribute (an interval-based trigger where the interval is measured from the start time of the previous task). This means it will run every 5 seconds from the start time of the previous task.

Starting from 06:00:31 up to 06:01:01, there are five intervals of 5 seconds each.
06:00:36
06:00:41
06:00:46
06:00:51
06:00:56
This means our FixedRateWorker has been queued 5 times. If we look at the logs from 06:01:01 to 06:01:41, FixedRateWorker has been executed 5 times. The point to take here is be careful when combining multiple schedules. We combined them here for the sake of completeness. Also, we've run the following example within a Spring MVC application just by adding an extra configuration spring-scheduler.xml

To see the output, please check the logs :) Feel free to modify the MVC app to fit your needs. You might wanna try integrating a web service with scheduling and show the results via MVC. The welcome page is accesible at
http://localhost:8080/spring-mvc-task-scheduling-xml/krams/main/welcome
The best way to learn further is to try the actual application.

Download the project
You can access the project site at Google's Project Hosting at http://code.google.com/p/spring-mvc-scheduling/

You can download the project as a Maven build. Look for the spring-mvc-task-scheduling-xml.zip in the Download sections.

You can run the project directly using an embedded server via Maven.
For Tomcat: mvn tomcat:run
For Jetty: mvn jetty:run

If you need to know more about Task Scheduling in Spring 3.0, please visit the following links:

StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Spring 3 - Task Scheduling via "scheduled-tasks" Element ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share