001/** 002 * Copyright 2014 Tampere University of Technology, Pori Department 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package core.tut.pori.context; 017 018import java.util.Date; 019import java.util.concurrent.ArrayBlockingQueue; 020import java.util.concurrent.ExecutorService; 021import java.util.concurrent.ThreadPoolExecutor; 022import java.util.concurrent.TimeUnit; 023 024import org.apache.log4j.Logger; 025import org.quartz.Scheduler; 026import org.quartz.SchedulerException; 027import org.quartz.impl.StdSchedulerFactory; 028 029import core.tut.pori.properties.ExecutorProperties; 030import core.tut.pori.utils.StringUtils; 031 032/** 033 * Handles system executors. 034 * 035 * This class can be used to retrieve instances of the system executor service and the quartz scheduler. 036 * 037 * This class requires PropertyHandler to be initialized. 038 * 039 * One should not initialize this handler directly, as an instantiated version is available from ServiceInitializer. 040 */ 041public class ExecutorHandler { 042 private static final Logger LOGGER = Logger.getLogger(ExecutorHandler.class); 043 private static final String QUARTZ_CONFIGURATION_FILE = "../quartz.properties"; 044 private static final String QUARTZ_SYSTEM_PROPERTY = "org.quartz.properties"; 045 private Scheduler _scheduler = null; 046 private ExecutorService _executor = null; 047 048 /** 049 * 050 */ 051 public void close() { 052 if(_scheduler != null){ 053 try { 054 _scheduler.shutdown(true); 055 } catch (SchedulerException ex) { 056 LOGGER.error(ex, ex); 057 } 058 } 059 if(_executor != null){ 060 _executor.shutdown(); 061 try { 062 _executor.awaitTermination(2, TimeUnit.SECONDS); //await for a short while before giving up 063 } catch (InterruptedException ex) { 064 LOGGER.error(ex, ex); 065 } 066 } 067 } 068 069 /** 070 * 071 * @throws IllegalArgumentException 072 */ 073 public ExecutorHandler() throws IllegalArgumentException{ 074 LOGGER.debug("Initializing handler..."); 075 Date started = new Date(); 076 System.setProperty(QUARTZ_SYSTEM_PROPERTY, QUARTZ_CONFIGURATION_FILE); // load quartz configuration 077 try { 078 _scheduler = StdSchedulerFactory.getDefaultScheduler(); 079 _scheduler.start(); 080 } catch (SchedulerException ex) { 081 LOGGER.error(ex, ex); 082 throw new IllegalArgumentException("Failed to initialize Scheduler."); 083 } 084 085 ExecutorProperties properties = ServiceInitializer.getPropertyHandler().getSystemProperties(ExecutorProperties.class); 086 _executor = new ThreadPoolExecutor(properties.getCoreCount(), properties.getPoolSize(), properties.getKeepAlive(), TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(properties.getQueueSize())); 087 088 LOGGER.debug("Property Handler initialized in "+StringUtils.getDurationString(started, new Date())); 089 } 090 091 /** 092 * Note: you should not run long-running background tasks, which may reserve the scheduler for a long time. 093 * If you need to do multiple functions, split the task to separate Jobs, and use triggers to launch new jobs. 094 * Especially, do NOT use sleep(), if you need to wait, schedule your job to re-run again at a later date. 095 * 096 * Do NOT close or cleanup the instances returned by this method, the initialization and destruction is handled automatically. 097 * 098 * @return quartz scheduler for background jobs 099 */ 100 public Scheduler getScheduler(){ 101 return _scheduler; 102 } 103 104 /** 105 * Note: if you are planning to run repetitive and non-time specific background tasks, you should implement Job and use getScheduler(). 106 * 107 * The scheduler is meant for short duration tasks. Do not abuse it. 108 * 109 * Do NOT close or cleanup the instances returned by this method, the initialization and destruction is handled automatically. 110 * 111 * @return the executor service 112 */ 113 public ExecutorService getExecutor() { 114 return _executor; 115 } 116}