All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.dashbuilder.scheduler.Scheduler Maven / Gradle / Ivy

There is a newer version: 1.0.0.Final
Show newest version
/**
 * Copyright 2012 Red Hat, Inc. and/or its affiliates.
 *
 * 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.dashbuilder.scheduler;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Task scheduler component.
 * 

It uses internally an instance of java.util.concurrent.ScheduledThreadPoolExecutor * which provides a thread pool and the delayed task execution capability.

*/ public class Scheduler { private Logger log = LoggerFactory.getLogger(Scheduler.class); protected PausableThreadPoolExecutor executor; protected ThreadFactory threadFactory; protected Map scheduledTasks = Collections.synchronizedMap(new HashMap()); protected int maxThreadPoolSize; public void init(int maxThreadPoolSize) { this.maxThreadPoolSize = maxThreadPoolSize; this.threadFactory = new SchedulerThreadFactory(); this.executor = new PausableThreadPoolExecutor(maxThreadPoolSize, threadFactory); this.executor.setContinueExistingPeriodicTasksAfterShutdownPolicy(false); this.executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false); log.debug("Scheduler started [pool size=" + maxThreadPoolSize + "]."); } public void shutdown() { log.debug("Scheduler shutdown started."); executor.shutdown(); log.debug("Scheduler shutdown completed."); } public int getMaxThreadPoolSize() { return maxThreadPoolSize; } public void setMaxThreadPoolSize(int maxThreadPoolSize) { this.maxThreadPoolSize = maxThreadPoolSize; if (executor != null) executor.setCorePoolSize(maxThreadPoolSize); } public int getThreadPoolSize() { return executor.getPoolSize(); } public ThreadFactory getThreadFactory() { return threadFactory; } public void setThreadFactory(ThreadFactory threadFactory) { this.threadFactory = threadFactory; } public int getNumberOfScheduledTasks() { return scheduledTasks.size(); } public int getNumberOfScheduledTasksInQueue() { return executor.getQueue().size(); } public SchedulerTask getTaskByKey(String key) { for (SchedulerTask task : scheduledTasks.values()) { if (task.getKey().equals(key)) { return task; } } return null; } public List getScheduledTasks() { return new ArrayList(scheduledTasks.values()); } public List getRunningTasks() { List result = new ArrayList(); for (SchedulerTask task : scheduledTasks.values()) { if (task.isRunning()) result.add(task); } return result; } public List getMisfiredTasks() { List result = new ArrayList(); for (SchedulerTask task : scheduledTasks.values()) { if (task.isMisfired()) result.add(task); } return result; } public List getWaitingTasks() { List result = new ArrayList(); for (SchedulerTask task : scheduledTasks.values()) { if (!task.isDone() && !task.isRunning() && !task.isMisfired()) result.add(task); } return result; } // Transactional operations public void pause() { executor.pause(); } public void resume() { executor.resume(); } public boolean isPaused() { return executor.isPaused(); } public synchronized void execute(SchedulerTask task) { try { _schedule(task, null); } catch (Exception e) { log.error("Execute call failed for task: " + task.getKey(), e); } } public synchronized void schedule(SchedulerTask task, Date date) { try { _schedule(task, date); } catch (Exception e) { log.error("Schedule call failed for task: " + task.getKey(), e); } } public synchronized void schedule(SchedulerTask task, long seconds) { try { _schedule(task, seconds); } catch (Exception e) { log.error("Schedule call failed for task: " + task.getKey(), e); } } public synchronized void unschedule(final String key) { try { _unschedule(key); } catch (Exception e) { log.error("Unschedule call failed for task: " + key, e); } } public synchronized void unscheduleAll() { try { _unscheduleAll(); } catch (Exception e) { log.error("Unschedule all call failed.", e); } } public synchronized void fireTask(String key) { SchedulerTask task = scheduledTasks.get(key); if (task != null && !task.isDone() && !task.isRunning()) { try { task.run(); log.debug("Task " + task + " executed."); } finally { scheduledTasks.remove(key); task.cancel(); _purge(); // Re-schedule fixed delay (repetitive) tasks after issue a fire. if (task.isFixedDelay()) { schedule(task, task.getFixedDelaySeconds()); } } } } // Scheduler business logic protected void _schedule(SchedulerTask task, Date date) { // Calculate the delay. // Never use a delay=0 in order to force the task to be launched in a separated thread. long delay = 10000; if (date != null) { Date now = new Date(); delay = date.getTime() - now.getTime(); if (delay <= 0) throw new IllegalArgumentException("Delay is negative. The task can not be scheduled [" + task.toString() + "] Date=" + date); } // Remove any old task (if any) _unschedule(task.getKey()); // Register the new task. task.future = executor.schedule(task, delay, TimeUnit.MILLISECONDS); scheduledTasks.put(task.getKey(), task); if (date == null) log.debug("Task " + task + " execution requested."); else log.debug("Task " + task + " scheduled to: " + date); } protected void _schedule(SchedulerTask task, long seconds) { // Remove any old task (if any) _unschedule(task.getKey()); // Register the new task. task.fixedDelay = true; task.fixedDelaySeconds = seconds; task.future = executor.scheduleWithFixedDelay(task, seconds, seconds, TimeUnit.SECONDS); scheduledTasks.put(task.getKey(), task); log.debug("Task " + task + " scheduled every " + seconds + " seconds."); } protected void _unschedule(String key) { SchedulerTask task = scheduledTasks.remove(key); if (task != null && !task.isDone() && !task.isRunning()) { task.cancel(); _purge(); log.debug("Task " + task + " unscheduled."); } } public void _unscheduleAll() { Collection tasks = scheduledTasks.values(); for (SchedulerTask task : tasks) { if (task != null && !task.isDone() && !task.isRunning()) { task.cancel(); } } executor.purge(); scheduledTasks.clear(); log.debug("All tasks unscheduled."); } protected void _purge() { executor.purge(); Iterator it = scheduledTasks.values().iterator(); while (it.hasNext()) { SchedulerTask task = it.next(); if (task.isDone()) { it.remove(); log.debug("Task " + task + " purged."); } } } public String printScheduledTasksReport() { Map temp = new HashMap(scheduledTasks); StringBuilder buf = new StringBuilder(); buf.append("\n\n------------------ SCHEDULED TASKS=").append(temp.size()) .append(" (Queue size=").append(executor.getQueue().size()).append(") -----------------------------\n"); for (Map.Entry entry : temp.entrySet()) { SchedulerTask task = entry.getValue(); buf.append("\n"); if (task.isRunning()) buf.append("RUNNING - "); else if (task.isCancelled()) buf.append("CANCELL - "); else if (task.isDone()) buf.append("COMPLTD - "); else buf.append("WAITING - [Firing in ").append(task.printTimeToFire()).append("] - "); buf.append("[").append(task).append("]"); } return buf.toString(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy