blob: bb02e200f849ce8736ac907fd9b23fd2dcefaec8 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.sling.commons.scheduler.impl;
import java.util.Date;
import java.util.Iterator;
import org.apache.sling.commons.threads.ThreadPool;
import org.apache.sling.commons.threads.ThreadPoolManager;
import org.quartz.SchedulerException;
import org.quartz.impl.DirectSchedulerFactory;
import org.quartz.simpl.RAMJobStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A per thread pool quartz scheduler
*/
public class SchedulerProxy {
private static final String PREFIX = "Apache Sling Quartz Scheduler ";
private static final String QUARTZ_SCHEDULER_NAME = "ApacheSling";
/** Default logger. */
private final Logger logger = LoggerFactory.getLogger(this.getClass());
/** The quartz scheduler. */
private final org.quartz.Scheduler scheduler;
private final ThreadPoolManager threadPoolManager;
private final ThreadPool threadPool;
private final String poolName;
public SchedulerProxy(final ThreadPoolManager manager,
final String pName) throws SchedulerException {
// sanity null check
if ( manager == null ) {
throw new SchedulerException("Thread pool manager missing");
}
if ( pName == null ) {
throw new SchedulerException("Thread pool name missing");
}
this.threadPoolManager = manager;
this.poolName = pName;
// create the pool
this.threadPool = this.threadPoolManager.get(poolName);
final QuartzThreadPool quartzPool = new QuartzThreadPool(this.threadPool);
boolean succeeded = false;
try {
final String name = QUARTZ_SCHEDULER_NAME + this.poolName.replace(' ', '_');
final DirectSchedulerFactory factory = DirectSchedulerFactory.getInstance();
// unique run id
final String runID = new Date().toString().replace(' ', '_') + this.hashCode();
factory.createScheduler(name, runID, quartzPool, new RAMJobStore());
// quartz does not provide a way to get the scheduler by name AND runID, so we have to iterate!
final Iterator<org.quartz.Scheduler> allSchedulersIter = factory.getAllSchedulers().iterator();
org.quartz.Scheduler s = null;
while ( s == null && allSchedulersIter.hasNext() ) {
final org.quartz.Scheduler current = allSchedulersIter.next();
if ( name.equals(current.getSchedulerName())
&& runID.equals(current.getSchedulerInstanceId()) ) {
s = current;
}
}
if ( s == null ) {
throw new SchedulerException("Unable to find new scheduler with name " + name + " and run ID " + runID);
}
s.start();
if ( this.logger.isDebugEnabled() ) {
this.logger.debug("{}for pool {} started.", PREFIX, poolName);
}
this.scheduler = s;
succeeded = true;
} finally {
if ( !succeeded) {
this.threadPoolManager.release(this.threadPool);
}
}
}
/**
* Dispose the quartz scheduler
*/
public void dispose() {
try {
this.scheduler.shutdown();
} catch (SchedulerException e) {
this.logger.debug("Exception during shutdown of scheduler.", e);
}
if ( this.logger.isDebugEnabled() ) {
this.logger.debug("{}for pool {} stopped.", PREFIX, poolName);
}
this.threadPoolManager.release(this.threadPool);
}
public org.quartz.Scheduler getScheduler() {
return this.scheduler;
}
}