Scheduled and Background Jobs in CQ5 (Sling)

There are certain scenarios where we would like a specific job to be scheduled once or at regular intervals within CQ5. There aren’t any tools or features in CQ5 specifically that allow this except for the Scheduler service in Sling which is uses Quartz internally. The Scheduler can be referenced from any OSGi component to schedule a Runnable class manually or we are able to deploy a service which implements runnable and provide some properties which influence how the job would be run by the scheduler. The following show examples of each:

1. Schedule job automatically (just by deployment of an osgi service representing the job)

 
@Service
@Component(name="News Cache Refresh Job", label="News Cache Refresh Job", description="News Cache Refresh Job", metatype=true)
@Properties({
		@Property(label="Quartz Cron Expression",description="Quartz Scheduler specific cron expression. Do not put unix cron expression",name="scheduler.expression", value="0 0/5 * * * ?"),
		@Property(
	        label="Allow concurrent executions",
	        description="Allow concurrent executions of this Scheduled Service",
	        name="scheduler.concurrent",
	        boolValue=false,
	        propertyPrivate=true
		),
		@Property(label="Job Enabled?",description="Turn on or off the news cache refresh job",
			name="news.cache.refresh.enabled",
			boolValue=false
		)
})
public class NewsCacheRefreshJob implements Runnable {
	
	private static Logger logger = LoggerFactory.getLogger(NewsCacheRefreshJob.class);
	public void run() {
	    logger.debug("Running NewsCacheRefreshJob");
	    //TODO	
		
	}

}

This is quite simple. The service class just needs to implement java.lang.Runnable and set the properties above. The main ones to notice are the cron expression (make sure this is the cron expression format for Quartz and not according to unix) and the scheduler.concurrent which affects whether multiple instances of the same job can run concurrently or queued.

2. Schedule the job manually (e.g. in an event handler based on some event)

    @Reference(target="(&(service.pid=my.company.news.services.NewsCacheRefreshJob))")
    private Runnable newsCacheRefreshJob;
    
    @Reference
    private Scheduler scheduler;
    
    public boolean process(Event arg0) {
        
        if(scheduler!=null && newsCacheRefreshJob!=null)
        {
            logger.debug("News Page Updated, running NewsCacheRefreshJob now");
            try {
                scheduler.fireJob(newsCacheRefreshJob, new HashMap<String,Serializable>());
                return true;
            } catch (Exception e) {
                logger.error("Exception occurred while firing news cache refresh job",e);
            }
            

        }
        return false;
    }

In the code above, we have a Scheduler and we have a reference to the specific job in 1 which we get using a target expression. You are free to just use another Runnable class and instantiate a new one if you are firing it off once via the scheduler. In the case where you want to schedule it from an activator, you can also create a new instance and schedule it by calling

scheduler.addPeriodicJob("myJob", job, null, period, true);

The information here is expanded upon in the following links:

http://dev.day.com/content/ddc/blog/2010/02/the_apache_slingsch.html

http://sling.apache.org/site/scheduler-service-commons-scheduler.html

Advertisements
Scheduled and Background Jobs in CQ5 (Sling)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s