/* */ package org.quartz.impl.jdbcjobstore;
/* */
/* */ import java.io.IOException;
/* */ import java.lang.reflect.Constructor;
/* */ import java.lang.reflect.InvocationTargetException;
/* */ import java.sql.Connection;
/* */ import java.sql.SQLException;
/* */ import java.util.Date;
/* */ import java.util.HashMap;
/* */ import java.util.Iterator;
/* */ import java.util.LinkedList;
/* */ import java.util.List;
/* */ import java.util.Set;
/* */ import org.apache.commons.logging.Log;
/* */ import org.apache.commons.logging.LogFactory;
/* */ import org.quartz.Calendar;
/* */ import org.quartz.CronTrigger;
/* */ import org.quartz.JobDataMap;
/* */ import org.quartz.JobDetail;
/* */ import org.quartz.JobPersistenceException;
/* */ import org.quartz.ObjectAlreadyExistsException;
/* */ import org.quartz.SchedulerConfigException;
/* */ import org.quartz.SchedulerException;
/* */ import org.quartz.SimpleTrigger;
/* */ import org.quartz.Trigger;
/* */ import org.quartz.core.SchedulingContext;
/* */ import org.quartz.spi.ClassLoadHelper;
/* */ import org.quartz.spi.JobStore;
/* */ import org.quartz.spi.SchedulerSignaler;
/* */ import org.quartz.spi.TriggerFiredBundle;
/* */ import org.quartz.utils.DBConnectionManager;
/* */ import org.quartz.utils.Key;
/* */ import org.quartz.utils.TriggerStatus;
/* */
/* */ public abstract class JobStoreSupport
/* */ implements JobStore, Constants
/* */ {
/* 76 */ protected static String LOCK_TRIGGER_ACCESS = "TRIGGER_ACCESS";
/* */
/* 78 */ protected static String LOCK_JOB_ACCESS = "JOB_ACCESS";
/* */
/* 80 */ protected static String LOCK_CALENDAR_ACCESS = "CALENDAR_ACCESS";
/* */
/* 82 */ protected static String LOCK_STATE_ACCESS = "STATE_ACCESS";
/* */
/* 84 */ protected static String LOCK_MISFIRE_ACCESS = "MISFIRE_ACCESS";
/* */ protected String dsName;
/* */ protected String tablePrefix;
/* */ protected boolean useProperties;
/* */ protected String instanceId;
/* */ protected String instanceName;
/* */ protected String delegateClassName;
/* */ protected Class delegateClass;
/* */ protected HashMap calendarCache;
/* */ private DriverDelegate delegate;
/* */ private long misfireThreshold;
/* */ private boolean dontSetAutoCommitFalse;
/* */ private boolean isClustered;
/* */ private boolean useDBLocks;
/* */ private boolean lockOnInsert;
/* */ private Semaphore lockHandler;
/* */ private String selectWithLockSQL;
/* */ private long clusterCheckinInterval;
/* */ private ClusterManager clusterManagementThread;
/* */ private MisfireHandler misfireHandler;
/* */ private ClassLoadHelper classLoadHelper;
/* */ private SchedulerSignaler signaler;
/* */ protected int maxToRecoverAtATime;
/* */ private boolean setTxIsolationLevelSequential;
/* */ private long dbRetryInterval;
/* */ private int lastRecoverCount;
/* 1725 */ private static long ftrCtr = System.currentTimeMillis();
/* */ protected boolean firstCheckIn;
/* */ protected long lastCheckin;
/* */
/* */ public JobStoreSupport()
/* */ {
/* 96 */ this.tablePrefix = "QRTZ_";
/* */
/* 98 */ this.useProperties = false;
/* */
/* 105 */ this.delegateClass = StdJDBCDelegate.class;
/* */
/* 107 */ this.calendarCache = new HashMap();
/* */
/* 111 */ this.misfireThreshold = 60000L;
/* */
/* 113 */ this.dontSetAutoCommitFalse = false;
/* */
/* 115 */ this.isClustered = false;
/* */
/* 117 */ this.useDBLocks = false;
/* */
/* 119 */ this.lockOnInsert = true;
/* */
/* 121 */ this.lockHandler = null;
/* */
/* 123 */ this.selectWithLockSQL = null;
/* */
/* 125 */ this.clusterCheckinInterval = 7500L;
/* */
/* 127 */ this.clusterManagementThread = null;
/* */
/* 129 */ this.misfireHandler = null;
/* */
/* 135 */ this.maxToRecoverAtATime = 20;
/* */
/* 137 */ this.setTxIsolationLevelSequential = false;
/* */
/* 139 */ this.dbRetryInterval = 10000L;
/* */
/* 729 */ this.lastRecoverCount = 0;
/* */
/* 2025 */ this.firstCheckIn = true;
/* */
/* 2027 */ this.lastCheckin = System.currentTimeMillis();
/* */ }
/* */
/* */ public void setDataSource(String dsName)
/* */ {
/* 156 */ this.dsName = dsName;
/* */ }
/* */
/* */ public String getDataSource()
/* */ {
/* 166 */ return this.dsName;
/* */ }
/* */
/* */ public void setTablePrefix(String prefix)
/* */ {
/* 175 */ if (prefix == null) prefix = "";
/* */
/* 177 */ this.tablePrefix = prefix;
/* */ }
/* */
/* */ public String getTablePrefix()
/* */ {
/* 186 */ return this.tablePrefix;
/* */ }
/* */
/* */ public void setUseProperties(String useProp)
/* */ {
/* 195 */ if (useProp == null) useProp = "false";
/* */
/* 197 */ this.useProperties = Boolean.valueOf(useProp).booleanValue();
/* */ }
/* */
/* */ public boolean canUseProperties()
/* */ {
/* 206 */ return this.useProperties;
/* */ }
/* */
/* */ public void setInstanceId(String instanceId)
/* */ {
/* 215 */ this.instanceId = instanceId;
/* */ }
/* */
/* */ public String getInstanceId()
/* */ {
/* 225 */ return this.instanceId;
/* */ }
/* */
/* */ public void setInstanceName(String instanceName)
/* */ {
/* 234 */ this.instanceName = instanceName;
/* */ }
/* */
/* */ public String getInstanceName()
/* */ {
/* 244 */ return this.instanceName;
/* */ }
/* */
/* */ public void setIsClustered(boolean isClustered)
/* */ {
/* 253 */ this.isClustered = isClustered;
/* */ }
/* */
/* */ public boolean isClustered()
/* */ {
/* 262 */ return this.isClustered;
/* */ }
/* */
/* */ public long getClusterCheckinInterval()
/* */ {
/* 273 */ return this.clusterCheckinInterval;
/* */ }
/* */
/* */ public void setClusterCheckinInterval(long l)
/* */ {
/* 284 */ this.clusterCheckinInterval = l;
/* */ }
/* */
/* */ public int getMaxMisfiresToHandleAtATime()
/* */ {
/* 295 */ return this.maxToRecoverAtATime;
/* */ }
/* */
/* */ public void setMaxMisfiresToHandleAtATime(int maxToRecoverAtATime)
/* */ {
/* 306 */ this.maxToRecoverAtATime = maxToRecoverAtATime;
/* */ }
/* */
/* */ public long getDbRetryInterval()
/* */ {
/* 313 */ return this.dbRetryInterval;
/* */ }
/* */
/* */ public void setDbRetryInterval(long dbRetryInterval)
/* */ {
/* 319 */ this.dbRetryInterval = dbRetryInterval;
/* */ }
/* */
/* */ public void setUseDBLocks(boolean useDBLocks)
/* */ {
/* 329 */ this.useDBLocks = useDBLocks;
/* */ }
/* */
/* */ public boolean getUseDBLocks()
/* */ {
/* 339 */ return this.useDBLocks;
/* */ }
/* */
/* */ public boolean isLockOnInsert() {
/* 343 */ return this.lockOnInsert;
/* */ }
/* */
/* */ public void setLockOnInsert(boolean lockOnInsert)
/* */ {
/* 359 */ this.lockOnInsert = lockOnInsert;
/* */ }
/* */
/* */ public long getMisfireThreshold() {
/* 363 */ return this.misfireThreshold;
/* */ }
/* */
/* */ public void setMisfireThreshold(long misfireThreshold)
/* */ {
/* 374 */ if (misfireThreshold < 1L) {
/* 375 */ throw new IllegalArgumentException("Misfirethreashold must be larger than 0");
/* */ }
/* 377 */ this.misfireThreshold = misfireThreshold;
/* */ }
/* */
/* */ public boolean isDontSetAutoCommitFalse() {
/* 381 */ return this.dontSetAutoCommitFalse;
/* */ }
/* */
/* */ public void setDontSetAutoCommitFalse(boolean b)
/* */ {
/* 392 */ this.dontSetAutoCommitFalse = b;
/* */ }
/* */
/* */ public boolean isTxIsolationLevelSerializable() {
/* 396 */ return this.setTxIsolationLevelSequential;
/* */ }
/* */
/* */ public void setTxIsolationLevelSerializable(boolean b)
/* */ {
/* 405 */ this.setTxIsolationLevelSequential = b;
/* */ }
/* */
/* */ public void setDriverDelegateClass(String delegateClassName)
/* */ throws InvalidConfigurationException
/* */ {
/* 419 */ this.delegateClassName = delegateClassName;
/* */ }
/* */
/* */ public String getDriverDelegateClass()
/* */ {
/* 430 */ return this.delegateClassName;
/* */ }
/* */
/* */ public String getSelectWithLockSQL() {
/* 434 */ return this.selectWithLockSQL;
/* */ }
/* */
/* */ public void setSelectWithLockSQL(String string)
/* */ {
/* 446 */ this.selectWithLockSQL = string;
/* */ }
/* */
/* */ protected ClassLoadHelper getClassLoadHelper() {
/* 450 */ return this.classLoadHelper;
/* */ }
/* */
/* */ Log getLog()
/* */ {
/* 458 */ return LogFactory.getLog(getClass());
/* */ }
/* */
/* */ public void initialize(ClassLoadHelper loadHelper, SchedulerSignaler signaler)
/* */ throws SchedulerConfigException
/* */ {
/* 470 */ if (this.dsName == null) throw new SchedulerConfigException("DataSource name not set.");
/* */
/* 473 */ this.classLoadHelper = loadHelper;
/* 474 */ this.signaler = signaler;
/* */
/* 476 */ if ((!getUseDBLocks()) && (!isClustered())) {
/* 477 */ getLog().info("Using thread monitor-based data access locking (synchronization).");
/* */
/* 480 */ this.lockHandler = new SimpleSemaphore();
/* */ } else {
/* 482 */ getLog().info("Using db table-based data access locking (synchronization).");
/* */
/* 485 */ this.lockHandler = new StdRowLockSemaphore(getTablePrefix(), getSelectWithLockSQL());
/* */ }
/* */
/* 489 */ if (!isClustered())
/* */ try {
/* 491 */ cleanVolatileTriggerAndJobs();
/* */ } catch (SchedulerException se) {
/* 493 */ throw new SchedulerConfigException("Failure occured during job recovery.", se);
/* */ }
/* */ }
/* */
/* */ public void schedulerStarted()
/* */ throws SchedulerException
/* */ {
/* 504 */ if (isClustered()) {
/* 505 */ this.clusterManagementThread = new ClusterManager(this);
/* 506 */ this.clusterManagementThread.initialize();
/* */ }
/* */ else {
/* */ try {
/* 510 */ recoverJobs();
/* */ } catch (SchedulerException se) {
/* 512 */ throw new SchedulerConfigException("Failure occured during job recovery.", se);
/* */ }
/* */
/* */ }
/* */
/* 517 */ this.misfireHandler = new MisfireHandler(this);
/* 518 */ this.misfireHandler.initialize();
/* */ }
/* */
/* */ public void shutdown()
/* */ {
/* 529 */ if (this.clusterManagementThread != null) {
/* 530 */ this.clusterManagementThread.shutdown();
/* */ }
/* 532 */ if (this.misfireHandler != null) this.misfireHandler.shutdown();
/* */ try
/* */ {
/* 535 */ DBConnectionManager.getInstance().shutdown(getDataSource());
/* */ } catch (SQLException sqle) {
/* 537 */ getLog().warn("Database connection shutdown unsuccessful.", sqle);
/* */ }
/* */ }
/* */
/* */ public boolean supportsPersistence() {
/* 542 */ return true;
/* */ }
/* */
/* */ protected Connection getConnection()
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 553 */ Connection conn = DBConnectionManager.getInstance().getConnection(getDataSource());
/* */
/* 556 */ if (conn == null) throw new SQLException("Could not get connection from DataSource '" + getDataSource() + "'");
/* */
/* */ try
/* */ {
/* 561 */ if (!isDontSetAutoCommitFalse()) conn.setAutoCommit(false);
/* */
/* 563 */ if (isTxIsolationLevelSerializable())
/* 564 */ conn.setTransactionIsolation(8);
/* */ } catch (SQLException ingore) {
/* */ } catch (Exception e) {
/* 567 */ if (conn != null) try {
/* 568 */ conn.close(); } catch (Throwable tt) {
/* */ } throw new JobPersistenceException("Failure setting up connection.", e);
/* */ }
/* */
/* 573 */ return conn;
/* */ } catch (SQLException sqle) {
/* 575 */ throw new JobPersistenceException("Failed to obtain DB connection from data source '" + getDataSource() + "': " + sqle.toString(), sqle);
/* */ }
/* */ catch (Exception e) {
/* */ }
/* 579 */ throw new JobPersistenceException("Failed to obtain DB connection from data source '" + getDataSource() + "': " + e.toString(), e, 499);
/* */ }
/* */
/* */ protected void releaseLock(Connection conn, String lockName, boolean doIt)
/* */ {
/* 587 */ if ((doIt) && (conn != null))
/* */ try {
/* 589 */ getLockHandler().releaseLock(conn, lockName);
/* */ } catch (LockException le) {
/* 591 */ getLog().error("Error returning lock: " + le.getMessage(), le);
/* */ }
/* */ }
/* */
/* */ protected abstract void cleanVolatileTriggerAndJobs()
/* */ throws JobPersistenceException;
/* */
/* */ protected void cleanVolatileTriggerAndJobs(Connection conn)
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 620 */ Key[] volatileTriggers = getDelegate().selectVolatileTriggers(conn);
/* 621 */ Key[] volatileJobs = getDelegate().selectVolatileJobs(conn);
/* */
/* 623 */ for (int i = 0; i < volatileTriggers.length; i++) {
/* 624 */ removeTrigger(conn, null, volatileTriggers[i].getName(), volatileTriggers[i].getGroup());
/* */ }
/* */
/* 627 */ getLog().info("Removed " + volatileTriggers.length + " Volatile Trigger(s).");
/* */
/* 631 */ for (int i = 0; i < volatileJobs.length; i++) {
/* 632 */ removeJob(conn, null, volatileJobs[i].getName(), volatileJobs[i].getGroup(), true);
/* */ }
/* */
/* 635 */ getLog().info("Removed " + volatileJobs.length + " Volatile Job(s).");
/* */
/* 639 */ getDelegate().deleteVolatileFiredTriggers(conn);
/* */ }
/* */ catch (Exception e) {
/* 642 */ throw new JobPersistenceException("Couldn't clean volatile data: " + e.getMessage(), e);
/* */ }
/* */ }
/* */
/* */ protected abstract void recoverJobs()
/* */ throws JobPersistenceException;
/* */
/* */ protected void recoverJobs(Connection conn)
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 670 */ int rows = getDelegate().updateTriggerStatesFromOtherStates(conn, "WAITING", "ACQUIRED", "BLOCKED");
/* */
/* 673 */ rows += getDelegate().updateTriggerStatesFromOtherStates(conn, "PAUSED", "PAUSED_BLOCKED", "PAUSED_BLOCKED");
/* */
/* 676 */ getLog().info("Freed " + rows + " triggers from 'acquired' / 'blocked' state.");
/* */
/* 681 */ getDelegate().updateTriggerStateFromOtherStatesBeforeTime(conn, "MISFIRED", "WAITING", "WAITING", getMisfireTime());
/* */
/* 684 */ recoverMisfiredJobs(conn, true);
/* */
/* 687 */ Trigger[] recoveringJobTriggers = getDelegate().selectTriggersForRecoveringJobs(conn);
/* */
/* 689 */ getLog().info("Recovering " + recoveringJobTriggers.length + " jobs that were in-progress at the time of the last shut-down.");
/* */
/* 695 */ for (int i = 0; i < recoveringJobTriggers.length; i++) {
/* 696 */ if (!jobExists(conn, recoveringJobTriggers[i].getJobName(), recoveringJobTriggers[i].getJobGroup()))
/* */ continue;
/* 698 */ recoveringJobTriggers[i].computeFirstFireTime(null);
/* 699 */ storeTrigger(conn, null, recoveringJobTriggers[i], null, false, "WAITING", false, true);
/* */ }
/* */
/* 703 */ getLog().info("Recovery complete.");
/* */
/* 706 */ Key[] ct = getDelegate().selectTriggersInState(conn, "COMPLETE");
/* 707 */ for (int i = 0; (ct != null) && (i < ct.length); i++)
/* 708 */ removeTrigger(conn, null, ct[i].getName(), ct[i].getGroup());
/* 709 */ getLog().info("Removed " + ct.length + " 'complete' triggers.");
/* */
/* 714 */ int n = getDelegate().deleteFiredTriggers(conn);
/* 715 */ getLog().info("Removed " + n + " stale fired job entries.");
/* */ } catch (Exception e) {
/* 717 */ throw new JobPersistenceException("Couldn't recover jobs: " + e.getMessage(), e);
/* */ }
/* */ }
/* */
/* */ protected long getMisfireTime()
/* */ {
/* 723 */ long misfireTime = System.currentTimeMillis();
/* 724 */ if (getMisfireThreshold() > 0L) misfireTime -= getMisfireThreshold();
/* */
/* 726 */ return misfireTime;
/* */ }
/* */
/* */ protected boolean recoverMisfiredJobs(Connection conn, boolean recovering)
/* */ throws JobPersistenceException, NoSuchDelegateException, SQLException, ClassNotFoundException, IOException
/* */ {
/* 735 */ Key[] misfiredTriggers = getDelegate().selectTriggersInState(conn, "MISFIRED");
/* */
/* 738 */ if ((misfiredTriggers.length > 0) && (misfiredTriggers.length > getMaxMisfiresToHandleAtATime())) {
/* 739 */ getLog().info("Handling " + getMaxMisfiresToHandleAtATime() + " of " + misfiredTriggers.length + " triggers that missed their scheduled fire-time.");
/* */ }
/* 746 */ else if (misfiredTriggers.length > 0) getLog().info("Handling " + misfiredTriggers.length + " triggers that missed their scheduled fire-time.");
/* */ else
/* */ {
/* 750 */ getLog().debug("Found 0 triggers that missed their scheduled fire-time.");
/* */ }
/* */
/* 753 */ this.lastRecoverCount = misfiredTriggers.length;
/* */
/* 755 */ for (int i = 0; (i < misfiredTriggers.length) && (i < getMaxMisfiresToHandleAtATime()); i++) {
/* 756 */ Trigger trig = getDelegate().selectTrigger(conn, misfiredTriggers[i].getName(), misfiredTriggers[i].getGroup());
/* */
/* 760 */ if (trig == null)
/* */ continue;
/* 762 */ Calendar cal = null;
/* 763 */ if (trig.getCalendarName() != null) {
/* 764 */ cal = retrieveCalendar(conn, null, trig.getCalendarName());
/* */ }
/* 766 */ String[] listeners = getDelegate().selectTriggerListeners(conn, trig.getName(), trig.getGroup());
/* */
/* 768 */ for (int l = 0; l < listeners.length; l++) {
/* 769 */ trig.addTriggerListener(listeners[l]);
/* */ }
/* */
/* 772 */ this.signaler.notifyTriggerListenersMisfired(trig);
/* */
/* 774 */ trig.updateAfterMisfire(cal);
/* */
/* 776 */ if (trig.getNextFireTime() == null) {
/* 777 */ storeTrigger(conn, null, trig, null, true, "COMPLETE", false, recovering);
/* */ }
/* */ else {
/* 780 */ storeTrigger(conn, null, trig, null, true, "WAITING", false, recovering);
/* */ }
/* */ }
/* */
/* 784 */ return misfiredTriggers.length > getMaxMisfiresToHandleAtATime();
/* */ }
/* */
/* */ protected boolean updateMisfiredTrigger(Connection conn, SchedulingContext ctxt, String triggerName, String groupName, String newStateIfNotComplete, boolean forceState)
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 797 */ Trigger trig = getDelegate().selectTrigger(conn, triggerName, groupName);
/* */
/* 800 */ long misfireTime = System.currentTimeMillis();
/* 801 */ if (getMisfireThreshold() > 0L) {
/* 802 */ misfireTime -= getMisfireThreshold();
/* */ }
/* 804 */ if (trig.getNextFireTime().getTime() > misfireTime) return false;
/* */
/* 806 */ Calendar cal = null;
/* 807 */ if (trig.getCalendarName() != null) {
/* 808 */ cal = retrieveCalendar(conn, ctxt, trig.getCalendarName());
/* */ }
/* 810 */ this.signaler.notifyTriggerListenersMisfired(trig);
/* */
/* 812 */ trig.updateAfterMisfire(cal);
/* */
/* 814 */ if (trig.getNextFireTime() == null) storeTrigger(conn, ctxt, trig, null, true, "COMPLETE", forceState, false);
/* */ else
/* */ {
/* 817 */ storeTrigger(conn, ctxt, trig, null, true, newStateIfNotComplete, forceState, false);
/* */ }
/* */
/* 821 */ return true;
/* */ } catch (Exception e) {
/* */ }
/* 824 */ throw new JobPersistenceException("Couldn't update misfired trigger '" + groupName + "." + triggerName + "': " + e.getMessage(), e);
/* */ }
/* */
/* */ protected void storeJob(Connection conn, SchedulingContext ctxt, JobDetail newJob, boolean replaceExisting)
/* */ throws ObjectAlreadyExistsException, JobPersistenceException
/* */ {
/* 838 */ if ((newJob.isVolatile()) && (isClustered())) {
/* 839 */ getLog().info("note: volatile jobs are effectively non-volatile in a clustered environment.");
/* */ }
/* */
/* 843 */ boolean existingJob = jobExists(conn, newJob.getName(), newJob.getGroup());
/* */ try
/* */ {
/* 846 */ if (existingJob) {
/* 847 */ if (!replaceExisting) throw new ObjectAlreadyExistsException(newJob);
/* */
/* 849 */ getDelegate().updateJobDetail(conn, newJob);
/* */ } else {
/* 851 */ getDelegate().insertJobDetail(conn, newJob);
/* */ }
/* */ } catch (IOException e) {
/* 854 */ throw new JobPersistenceException("Couldn't store job: " + e.getMessage(), e);
/* */ }
/* */ catch (SQLException e) {
/* 857 */ throw new JobPersistenceException("Couldn't store job: " + e.getMessage(), e);
/* */ }
/* */ }
/* */
/* */ protected boolean jobExists(Connection conn, String jobName, String groupName)
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 870 */ return getDelegate().jobExists(conn, jobName, groupName); } catch (SQLException e) {
/* */ }
/* 872 */ throw new JobPersistenceException("Couldn't determine job existence (" + groupName + "." + jobName + "): " + e.getMessage(), e);
/* */ }
/* */
/* */ protected void storeTrigger(Connection conn, SchedulingContext ctxt, Trigger newTrigger, JobDetail job, boolean replaceExisting, String state, boolean forceState, boolean recovering)
/* */ throws ObjectAlreadyExistsException, JobPersistenceException
/* */ {
/* 887 */ if ((newTrigger.isVolatile()) && (isClustered())) {
/* 888 */ getLog().info("note: volatile triggers are effectively non-volatile in a clustered environment.");
/* */ }
/* */
/* 892 */ boolean existingTrigger = triggerExists(conn, newTrigger.getName(), newTrigger.getGroup());
/* */ try
/* */ {
/* 897 */ boolean shouldBepaused = false;
/* */
/* 899 */ if (!forceState) {
/* 900 */ shouldBepaused = getDelegate().isTriggerGroupPaused(conn, newTrigger.getGroup());
/* */
/* 903 */ if (!shouldBepaused) {
/* 904 */ shouldBepaused = getDelegate().isTriggerGroupPaused(conn, "_$_ALL_GROUPS_PAUSED_$_");
/* */
/* 907 */ if (shouldBepaused) {
/* 908 */ getDelegate().insertPausedTriggerGroup(conn, newTrigger.getGroup());
/* */ }
/* */ }
/* */
/* 912 */ if ((shouldBepaused) && ((state.equals("WAITING")) || (state.equals("ACQUIRED")))) {
/* 913 */ state = "PAUSED";
/* */ }
/* */ }
/* 916 */ if (job == null) {
/* 917 */ job = getDelegate().selectJobDetail(conn, newTrigger.getJobName(), newTrigger.getJobGroup(), getClassLoadHelper());
/* */ }
/* */
/* 921 */ if (job == null) {
/* 922 */ throw new JobPersistenceException("The job (" + newTrigger.getFullJobName() + ") referenced by the trigger does not exist.");
/* */ }
/* */
/* 925 */ if ((job.isVolatile()) && (!newTrigger.isVolatile())) {
/* 926 */ throw new JobPersistenceException("It does not make sense to associate a non-volatile Trigger with a volatile Job!");
/* */ }
/* */
/* 930 */ if ((job.isStateful()) && (!recovering)) {
/* 931 */ String bstate = getNewStatusForTrigger(conn, ctxt, job.getName(), job.getGroup());
/* */
/* 933 */ if (("BLOCKED".equals(bstate)) && ("WAITING".equals(state)))
/* 934 */ state = "BLOCKED";
/* 935 */ if (("BLOCKED".equals(bstate)) && ("PAUSED".equals(state)))
/* 936 */ state = "PAUSED_BLOCKED";
/* */ }
/* 938 */ if (existingTrigger) {
/* 939 */ if (!replaceExisting) throw new ObjectAlreadyExistsException(newTrigger);
/* */
/* 941 */ if ((newTrigger instanceof SimpleTrigger)) {
/* 942 */ getDelegate().updateSimpleTrigger(conn, (SimpleTrigger)newTrigger);
/* */ }
/* 944 */ else if ((newTrigger instanceof CronTrigger)) {
/* 945 */ getDelegate().updateCronTrigger(conn, (CronTrigger)newTrigger);
/* */ }
/* */ else {
/* 948 */ getDelegate().updateBlobTrigger(conn, newTrigger);
/* */ }
/* 950 */ getDelegate().updateTrigger(conn, newTrigger, state, job);
/* */ } else {
/* 952 */ getDelegate().insertTrigger(conn, newTrigger, state, job);
/* 953 */ if ((newTrigger instanceof SimpleTrigger)) {
/* 954 */ getDelegate().insertSimpleTrigger(conn, (SimpleTrigger)newTrigger);
/* */ }
/* 956 */ else if ((newTrigger instanceof CronTrigger)) {
/* 957 */ getDelegate().insertCronTrigger(conn, (CronTrigger)newTrigger);
/* */ }
/* */ else
/* 960 */ getDelegate().insertBlobTrigger(conn, newTrigger);
/* */ }
/* */ }
/* */ catch (Exception e) {
/* 964 */ throw new JobPersistenceException("Couldn't store trigger: " + e.getMessage(), e);
/* */ }
/* */ }
/* */
/* */ protected boolean triggerExists(Connection conn, String triggerName, String groupName)
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 977 */ return getDelegate().triggerExists(conn, triggerName, groupName); } catch (SQLException e) {
/* */ }
/* 979 */ throw new JobPersistenceException("Couldn't determine trigger existence (" + groupName + "." + triggerName + "): " + e.getMessage(), e);
/* */ }
/* */
/* */ protected boolean removeJob(Connection conn, SchedulingContext ctxt, String jobName, String groupName, boolean activeDeleteSafe)
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 990 */ Key[] jobTriggers = getDelegate().selectTriggerNamesForJob(conn, jobName, groupName);
/* */
/* 992 */ for (int i = 0; i < jobTriggers.length; i++) {
/* 993 */ getDelegate().deleteSimpleTrigger(conn, jobTriggers[i].getName(), jobTriggers[i].getGroup());
/* */
/* 995 */ getDelegate().deleteCronTrigger(conn, jobTriggers[i].getName(), jobTriggers[i].getGroup());
/* */
/* 997 */ getDelegate().deleteBlobTrigger(conn, jobTriggers[i].getName(), jobTriggers[i].getGroup());
/* */
/* 999 */ getDelegate().deleteTriggerListeners(conn, jobTriggers[i].getName(), jobTriggers[i].getGroup());
/* */
/* 1001 */ getDelegate().deleteTrigger(conn, jobTriggers[i].getName(), jobTriggers[i].getGroup());
/* */ }
/* */
/* 1005 */ getDelegate().deleteJobListeners(conn, jobName, groupName);
/* */
/* 1008 */ return getDelegate().deleteJobDetail(conn, jobName, groupName) > 0;
/* */ }
/* */ catch (SQLException e)
/* */ {
/* */ }
/* */
/* 1013 */ throw new JobPersistenceException("Couldn't remove job: " + e.getMessage(), e);
/* */ }
/* */
/* */ protected JobDetail retrieveJob(Connection conn, SchedulingContext ctxt, String jobName, String groupName)
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 1021 */ JobDetail job = getDelegate().selectJobDetail(conn, jobName, groupName, getClassLoadHelper());
/* */
/* 1023 */ String[] listeners = getDelegate().selectJobListeners(conn, jobName, groupName);
/* */
/* 1025 */ for (int i = 0; i < listeners.length; i++) {
/* 1026 */ job.addJobListener(listeners[i]);
/* */ }
/* */
/* 1029 */ return job;
/* */ } catch (ClassNotFoundException e) {
/* 1031 */ throw new JobPersistenceException("Couldn't retrieve job because a required class was not found: " + e.getMessage(), e, 410);
/* */ }
/* */ catch (IOException e)
/* */ {
/* 1036 */ throw new JobPersistenceException("Couldn't retrieve job because the BLOB couldn't be deserialized: " + e.getMessage(), e, 410);
/* */ }
/* */ catch (SQLException e)
/* */ {
/* */ }
/* 1041 */ throw new JobPersistenceException("Couldn't retrieve job: " + e.getMessage(), e);
/* */ }
/* */
/* */ protected boolean removeTrigger(Connection conn, SchedulingContext ctxt, String triggerName, String groupName)
/* */ throws JobPersistenceException
/* */ {
/* 1049 */ boolean removedTrigger = false;
/* */ try
/* */ {
/* 1052 */ JobDetail job = getDelegate().selectJobForTrigger(conn, triggerName, groupName, getClassLoadHelper());
/* */
/* 1055 */ getDelegate().deleteSimpleTrigger(conn, triggerName, groupName);
/* 1056 */ getDelegate().deleteCronTrigger(conn, triggerName, groupName);
/* 1057 */ getDelegate().deleteBlobTrigger(conn, triggerName, groupName);
/* 1058 */ getDelegate().deleteTriggerListeners(conn, triggerName, groupName);
/* 1059 */ removedTrigger = getDelegate().deleteTrigger(conn, triggerName, groupName) > 0;
/* */
/* 1062 */ if ((null != job) && (!job.isDurable())) {
/* 1063 */ int numTriggers = getDelegate().selectNumTriggersForJob(conn, job.getName(), job.getGroup());
/* */
/* 1065 */ if (numTriggers == 0)
/* 1066 */ removeJob(conn, ctxt, job.getName(), job.getGroup(), true);
/* */ }
/* */ }
/* */ catch (ClassNotFoundException e) {
/* 1070 */ throw new JobPersistenceException("Couldn't remove trigger: " + e.getMessage(), e);
/* */ }
/* */ catch (SQLException e) {
/* 1073 */ throw new JobPersistenceException("Couldn't remove trigger: " + e.getMessage(), e);
/* */ }
/* */
/* 1077 */ return removedTrigger;
/* */ }
/* */
/* */ protected boolean replaceTrigger(Connection conn, SchedulingContext ctxt, String triggerName, String groupName, Trigger newTrigger)
/* */ throws JobPersistenceException
/* */ {
/* 1083 */ boolean removedTrigger = false;
/* */ try
/* */ {
/* 1086 */ JobDetail job = getDelegate().selectJobForTrigger(conn, triggerName, groupName, getClassLoadHelper());
/* */
/* 1089 */ if (job == null) {
/* 1090 */ return false;
/* */ }
/* 1092 */ if ((!newTrigger.getJobName().equals(job.getName())) || (!newTrigger.getJobGroup().equals(job.getGroup())))
/* */ {
/* 1094 */ throw new JobPersistenceException("New trigger is not related to the same job as the old trigger.");
/* */ }
/* 1096 */ getDelegate().deleteSimpleTrigger(conn, triggerName, groupName);
/* 1097 */ getDelegate().deleteCronTrigger(conn, triggerName, groupName);
/* 1098 */ getDelegate().deleteBlobTrigger(conn, triggerName, groupName);
/* 1099 */ getDelegate().deleteTriggerListeners(conn, triggerName, groupName);
/* 1100 */ removedTrigger = getDelegate().deleteTrigger(conn, triggerName, groupName) > 0;
/* */
/* 1103 */ storeTrigger(conn, ctxt, newTrigger, job, false, "WAITING", false, false);
/* */ }
/* */ catch (ClassNotFoundException e) {
/* 1106 */ throw new JobPersistenceException("Couldn't remove trigger: " + e.getMessage(), e);
/* */ }
/* */ catch (SQLException e) {
/* 1109 */ throw new JobPersistenceException("Couldn't remove trigger: " + e.getMessage(), e);
/* */ }
/* */
/* 1113 */ return removedTrigger;
/* */ }
/* */
/* */ protected Trigger retrieveTrigger(Connection conn, SchedulingContext ctxt, String triggerName, String groupName) throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 1120 */ Trigger trigger = getDelegate().selectTrigger(conn, triggerName, groupName);
/* */
/* 1122 */ if (trigger == null) return null;
/* 1123 */ String[] listeners = getDelegate().selectTriggerListeners(conn, triggerName, groupName);
/* */
/* 1125 */ for (int i = 0; i < listeners.length; i++) {
/* 1126 */ trigger.addTriggerListener(listeners[i]);
/* */ }
/* */
/* 1129 */ return trigger; } catch (Exception e) {
/* */ }
/* 1131 */ throw new JobPersistenceException("Couldn't retrieve trigger: " + e.getMessage(), e);
/* */ }
/* */
/* */ public int getTriggerState(Connection conn, SchedulingContext ctxt, String triggerName, String groupName)
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 1140 */ String ts = getDelegate().selectTriggerState(conn, triggerName, groupName);
/* */
/* 1143 */ if (ts == null) return -1;
/* */
/* 1145 */ if (ts.equals("DELETED")) return -1;
/* */
/* 1147 */ if (ts.equals("COMPLETE")) return 2;
/* */
/* 1149 */ if (ts.equals("PAUSED")) return 1;
/* */
/* 1151 */ if (ts.equals("PAUSED_BLOCKED")) return 1;
/* */
/* 1153 */ if (ts.equals("ERROR")) return 3;
/* */
/* 1155 */ if (ts.equals("BLOCKED")) return 4;
/* */
/* 1157 */ return 0;
/* */ } catch (SQLException e) {
/* */ }
/* 1160 */ throw new JobPersistenceException("Couldn't determine state of trigger (" + groupName + "." + triggerName + "): " + e.getMessage(), e);
/* */ }
/* */
/* */ protected void storeCalendar(Connection conn, SchedulingContext ctxt, String calName, Calendar calendar, boolean replaceExisting, boolean updateTriggers)
/* */ throws ObjectAlreadyExistsException, JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 1170 */ boolean existingCal = calendarExists(conn, calName);
/* 1171 */ if ((existingCal) && (!replaceExisting)) throw new ObjectAlreadyExistsException("Calendar with name '" + calName + "' already exists.");
/* */
/* 1174 */ if (existingCal) {
/* 1175 */ if (getDelegate().updateCalendar(conn, calName, calendar) < 1) throw new JobPersistenceException("Couldn't store calendar. Update failed.");
/* */
/* 1178 */ if (updateTriggers) {
/* 1179 */ Trigger[] trigs = getDelegate().selectTriggersForCalendar(conn, calName);
/* */
/* 1181 */ for (int i = 0; i < trigs.length; i++) {
/* 1182 */ trigs[i].updateWithNewCalendar(calendar, getMisfireThreshold());
/* 1183 */ storeTrigger(conn, ctxt, trigs[i], null, true, "WAITING", false, false);
/* */ }
/* */ }
/* */ }
/* 1187 */ else if (getDelegate().insertCalendar(conn, calName, calendar) < 1) { throw new JobPersistenceException("Couldn't store calendar. Insert failed.");
/* */ }
/* */
/* 1191 */ this.calendarCache.put(calName, calendar);
/* */ }
/* */ catch (IOException e) {
/* 1194 */ throw new JobPersistenceException("Couldn't store calendar because the BLOB couldn't be serialized: " + e.getMessage(), e);
/* */ }
/* */ catch (ClassNotFoundException e)
/* */ {
/* 1198 */ throw new JobPersistenceException("Couldn't store calendar: " + e.getMessage(), e);
/* */ }
/* */ catch (SQLException e) {
/* 1201 */ throw new JobPersistenceException("Couldn't store calendar: " + e.getMessage(), e);
/* */ }
/* */ }
/* */
/* */ protected boolean calendarExists(Connection conn, String calName) throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 1209 */ return getDelegate().calendarExists(conn, calName); } catch (SQLException e) {
/* */ }
/* 1211 */ throw new JobPersistenceException("Couldn't determine calendar existence (" + calName + "): " + e.getMessage(), e);
/* */ }
/* */
/* */ protected boolean removeCalendar(Connection conn, SchedulingContext ctxt, String calName)
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 1220 */ if (getDelegate().calendarIsReferenced(conn, calName)) throw new JobPersistenceException("Calender cannot be removed if it referenced by a trigger!");
/* */
/* 1223 */ this.calendarCache.remove(calName);
/* */
/* 1225 */ return getDelegate().deleteCalendar(conn, calName) > 0; } catch (SQLException e) {
/* */ }
/* 1227 */ throw new JobPersistenceException("Couldn't remove calendar: " + e.getMessage(), e);
/* */ }
/* */
/* */ protected Calendar retrieveCalendar(Connection conn, SchedulingContext ctxt, String calName)
/* */ throws JobPersistenceException
/* */ {
/* 1237 */ Calendar cal = (Calendar)this.calendarCache.get(calName);
/* 1238 */ if (cal != null) return cal;
/* */ try
/* */ {
/* 1241 */ cal = getDelegate().selectCalendar(conn, calName);
/* 1242 */ this.calendarCache.put(calName, cal);
/* 1243 */ return cal;
/* */ } catch (ClassNotFoundException e) {
/* 1245 */ throw new JobPersistenceException("Couldn't retrieve calendar because a required class was not found: " + e.getMessage(), e);
/* */ }
/* */ catch (IOException e)
/* */ {
/* 1249 */ throw new JobPersistenceException("Couldn't retrieve calendar because the BLOB couldn't be deserialized: " + e.getMessage(), e);
/* */ }
/* */ catch (SQLException e) {
/* */ }
/* 1253 */ throw new JobPersistenceException("Couldn't retrieve calendar: " + e.getMessage(), e);
/* */ }
/* */
/* */ protected int getNumberOfJobs(Connection conn, SchedulingContext ctxt)
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 1261 */ return getDelegate().selectNumJobs(conn); } catch (SQLException e) {
/* */ }
/* 1263 */ throw new JobPersistenceException("Couldn't obtain number of jobs: " + e.getMessage(), e);
/* */ }
/* */
/* */ protected int getNumberOfTriggers(Connection conn, SchedulingContext ctxt)
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 1271 */ return getDelegate().selectNumTriggers(conn); } catch (SQLException e) {
/* */ }
/* 1273 */ throw new JobPersistenceException("Couldn't obtain number of triggers: " + e.getMessage(), e);
/* */ }
/* */
/* */ protected int getNumberOfCalendars(Connection conn, SchedulingContext ctxt)
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 1281 */ return getDelegate().selectNumCalendars(conn); } catch (SQLException e) {
/* */ }
/* 1283 */ throw new JobPersistenceException("Couldn't obtain number of calendars: " + e.getMessage(), e);
/* */ }
/* */
/* */ protected String[] getJobNames(Connection conn, SchedulingContext ctxt, String groupName)
/* */ throws JobPersistenceException
/* */ {
/* 1290 */ String[] jobNames = null;
/* */ try
/* */ {
/* 1293 */ jobNames = getDelegate().selectJobsInGroup(conn, groupName);
/* */ } catch (SQLException e) {
/* 1295 */ throw new JobPersistenceException("Couldn't obtain job names: " + e.getMessage(), e);
/* */ }
/* */
/* 1299 */ return jobNames;
/* */ }
/* */
/* */ protected String[] getTriggerNames(Connection conn, SchedulingContext ctxt, String groupName)
/* */ throws JobPersistenceException
/* */ {
/* 1305 */ String[] trigNames = null;
/* */ try
/* */ {
/* 1308 */ trigNames = getDelegate().selectTriggersInGroup(conn, groupName);
/* */ } catch (SQLException e) {
/* 1310 */ throw new JobPersistenceException("Couldn't obtain trigger names: " + e.getMessage(), e);
/* */ }
/* */
/* 1314 */ return trigNames;
/* */ }
/* */
/* */ protected String[] getJobGroupNames(Connection conn, SchedulingContext ctxt)
/* */ throws JobPersistenceException
/* */ {
/* 1320 */ String[] groupNames = null;
/* */ try
/* */ {
/* 1323 */ groupNames = getDelegate().selectJobGroups(conn);
/* */ } catch (SQLException e) {
/* 1325 */ throw new JobPersistenceException("Couldn't obtain job groups: " + e.getMessage(), e);
/* */ }
/* */
/* 1329 */ return groupNames;
/* */ }
/* */
/* */ protected String[] getTriggerGroupNames(Connection conn, SchedulingContext ctxt)
/* */ throws JobPersistenceException
/* */ {
/* 1335 */ String[] groupNames = null;
/* */ try
/* */ {
/* 1338 */ groupNames = getDelegate().selectTriggerGroups(conn);
/* */ } catch (SQLException e) {
/* 1340 */ throw new JobPersistenceException("Couldn't obtain trigger groups: " + e.getMessage(), e);
/* */ }
/* */
/* 1344 */ return groupNames;
/* */ }
/* */
/* */ protected String[] getCalendarNames(Connection conn, SchedulingContext ctxt) throws JobPersistenceException
/* */ {
/* */ try {
/* 1350 */ return getDelegate().selectCalendars(conn); } catch (SQLException e) {
/* */ }
/* 1352 */ throw new JobPersistenceException("Couldn't obtain trigger groups: " + e.getMessage(), e);
/* */ }
/* */
/* */ protected Trigger[] getTriggersForJob(Connection conn, SchedulingContext ctxt, String jobName, String groupName)
/* */ throws JobPersistenceException
/* */ {
/* 1360 */ Trigger[] array = null;
/* */ try
/* */ {
/* 1363 */ array = getDelegate().selectTriggersForJob(conn, jobName, groupName);
/* */ }
/* */ catch (Exception e) {
/* 1366 */ throw new JobPersistenceException("Couldn't obtain triggers for job: " + e.getMessage(), e);
/* */ }
/* */
/* 1370 */ return array;
/* */ }
/* */
/* */ public void pauseTrigger(Connection conn, SchedulingContext ctxt, String triggerName, String groupName)
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 1385 */ String oldState = getDelegate().selectTriggerState(conn, triggerName, groupName);
/* */
/* 1388 */ if ((oldState.equals("WAITING")) || (oldState.equals("ACQUIRED")))
/* */ {
/* 1391 */ getDelegate().updateTriggerState(conn, triggerName, groupName, "PAUSED");
/* */ }
/* 1394 */ else if (oldState.equals("BLOCKED"))
/* 1395 */ getDelegate().updateTriggerState(conn, triggerName, groupName, "PAUSED_BLOCKED");
/* */ }
/* */ catch (SQLException e)
/* */ {
/* 1399 */ throw new JobPersistenceException("Couldn't pause trigger '" + groupName + "." + triggerName + "': " + e.getMessage(), e);
/* */ }
/* */ }
/* */
/* */ protected String getStatusForResumedTrigger(Connection conn, SchedulingContext ctxt, TriggerStatus status)
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 1409 */ String newState = "WAITING";
/* */
/* 1411 */ List lst = getDelegate().selectFiredTriggerRecordsByJob(conn, status.getJobKey().getName(), status.getJobKey().getGroup());
/* */
/* 1416 */ if (lst.size() > 0) {
/* 1417 */ FiredTriggerRecord rec = (FiredTriggerRecord)lst.get(0);
/* 1418 */ if (rec.isJobIsStateful())
/* */ {
/* 1421 */ newState = "BLOCKED";
/* */ }
/* */ }
/* 1424 */ return newState;
/* */ } catch (SQLException e) {
/* */ }
/* 1427 */ throw new JobPersistenceException("Couldn't determine new state in order to resume trigger '" + status.getKey().getGroup() + "." + status.getKey().getName() + "': " + e.getMessage(), e);
/* */ }
/* */
/* */ protected String getNewStatusForTrigger(Connection conn, SchedulingContext ctxt, String jobName, String groupName)
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 1441 */ String newState = "WAITING";
/* */
/* 1443 */ List lst = getDelegate().selectFiredTriggerRecordsByJob(conn, jobName, groupName);
/* */
/* 1446 */ if (lst.size() > 0) {
/* 1447 */ FiredTriggerRecord rec = (FiredTriggerRecord)lst.get(0);
/* 1448 */ if (rec.isJobIsStateful())
/* */ {
/* 1451 */ newState = "BLOCKED";
/* */ }
/* */ }
/* 1454 */ return newState;
/* */ } catch (SQLException e) {
/* */ }
/* 1457 */ throw new JobPersistenceException("Couldn't determine state for new trigger: " + e.getMessage(), e);
/* */ }
/* */
/* */ public void resumeTrigger(Connection conn, SchedulingContext ctxt, String triggerName, String groupName)
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 1510 */ TriggerStatus status = getDelegate().selectTriggerStatus(conn, triggerName, groupName);
/* */
/* 1513 */ if ((status == null) || (status.getNextFireTime() == null)) return;
/* */
/* 1515 */ boolean blocked = false;
/* 1516 */ if ("PAUSED_BLOCKED".equals(status.getStatus())) {
/* 1517 */ blocked = true;
/* */ }
/* 1519 */ String newState = getStatusForResumedTrigger(conn, ctxt, status);
/* */
/* 1521 */ boolean misfired = false;
/* */
/* 1523 */ if (status.getNextFireTime().before(new Date())) {
/* 1524 */ misfired = updateMisfiredTrigger(conn, ctxt, triggerName, groupName, newState, true);
/* */ }
/* */
/* 1528 */ if (!misfired) {
/* 1529 */ if (blocked) {
/* 1530 */ getDelegate().updateTriggerStateFromOtherState(conn, triggerName, groupName, newState, "PAUSED_BLOCKED");
/* */ }
/* */ else
/* 1533 */ getDelegate().updateTriggerStateFromOtherState(conn, triggerName, groupName, newState, "PAUSED");
/* */ }
/* */ }
/* */ catch (SQLException e)
/* */ {
/* 1538 */ throw new JobPersistenceException("Couldn't resume trigger '" + groupName + "." + triggerName + "': " + e.getMessage(), e);
/* */ }
/* */ }
/* */
/* */ public void pauseTriggerGroup(Connection conn, SchedulingContext ctxt, String groupName)
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 1556 */ getDelegate().updateTriggerGroupStateFromOtherStates(conn, groupName, "PAUSED", "ACQUIRED", "WAITING", "WAITING");
/* */
/* 1560 */ getDelegate().updateTriggerGroupStateFromOtherState(conn, groupName, "PAUSED_BLOCKED", "BLOCKED");
/* */
/* 1563 */ if (!getDelegate().isTriggerGroupPaused(conn, groupName))
/* 1564 */ getDelegate().insertPausedTriggerGroup(conn, groupName);
/* */ }
/* */ catch (SQLException e)
/* */ {
/* 1568 */ throw new JobPersistenceException("Couldn't pause trigger group '" + groupName + "': " + e.getMessage(), e);
/* */ }
/* */ }
/* */
/* */ public Set getPausedTriggerGroups(Connection conn, SchedulingContext ctxt)
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 1585 */ return getDelegate().selectPausedTriggerGroups(conn); } catch (SQLException e) {
/* */ }
/* 1587 */ throw new JobPersistenceException("Couldn't determine paused trigger groups: " + e.getMessage(), e);
/* */ }
/* */
/* */ public void resumeTriggerGroup(Connection conn, SchedulingContext ctxt, String groupName)
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 1610 */ getDelegate().deletePausedTriggerGroup(conn, groupName);
/* */
/* 1612 */ String[] trigNames = getDelegate().selectTriggersInGroup(conn, groupName);
/* */
/* 1615 */ for (int i = 0; i < trigNames.length; i++) {
/* 1616 */ resumeTrigger(conn, ctxt, trigNames[i], groupName);
/* */ }
/* */
/* */ }
/* */ catch (SQLException e)
/* */ {
/* 1653 */ throw new JobPersistenceException("Couldn't pause trigger group '" + groupName + "': " + e.getMessage(), e);
/* */ }
/* */ }
/* */
/* */ public void pauseAll(Connection conn, SchedulingContext ctxt)
/* */ throws JobPersistenceException
/* */ {
/* 1675 */ String[] names = getTriggerGroupNames(conn, ctxt);
/* */
/* 1677 */ for (int i = 0; i < names.length; i++) {
/* 1678 */ pauseTriggerGroup(conn, ctxt, names[i]);
/* */ }
/* */ try
/* */ {
/* 1682 */ if (!getDelegate().isTriggerGroupPaused(conn, "_$_ALL_GROUPS_PAUSED_$_"))
/* 1683 */ getDelegate().insertPausedTriggerGroup(conn, "_$_ALL_GROUPS_PAUSED_$_");
/* */ }
/* */ catch (SQLException e)
/* */ {
/* 1687 */ throw new JobPersistenceException("Couldn't pause all trigger groups: " + e.getMessage(), e);
/* */ }
/* */ }
/* */
/* */ public void resumeAll(Connection conn, SchedulingContext ctxt)
/* */ throws JobPersistenceException
/* */ {
/* 1710 */ String[] names = getTriggerGroupNames(conn, ctxt);
/* */
/* 1712 */ for (int i = 0; i < names.length; i++) {
/* 1713 */ resumeTriggerGroup(conn, ctxt, names[i]);
/* */ }
/* */ try
/* */ {
/* 1717 */ getDelegate().deletePausedTriggerGroup(conn, "_$_ALL_GROUPS_PAUSED_$_");
/* */ } catch (SQLException e) {
/* 1719 */ throw new JobPersistenceException("Couldn't resume all trigger groups: " + e.getMessage(), e);
/* */ }
/* */ }
/* */
/* */ protected synchronized String getFiredTriggerRecordId()
/* */ {
/* 1728 */ return getInstanceId() + ftrCtr++;
/* */ }
/* */
/* */ protected Trigger acquireNextTrigger(Connection conn, SchedulingContext ctxt, long noLaterThan)
/* */ throws JobPersistenceException
/* */ {
/* 1735 */ Trigger nextTrigger = null;
/* */
/* 1737 */ boolean acquiredOne = false;
/* */ do {
/* */ try
/* */ {
/* 1741 */ getDelegate().updateTriggerStateFromOtherStatesBeforeTime(conn, "MISFIRED", "WAITING", "WAITING", getMisfireTime());
/* */
/* 1745 */ long nextFireTime = getDelegate().selectNextFireTime(conn);
/* */
/* 1747 */ if ((nextFireTime == 0L) || (nextFireTime > noLaterThan)) {
/* 1748 */ return null;
/* */ }
/* 1750 */ Key triggerKey = null;
/* */ do {
/* 1752 */ triggerKey = getDelegate().selectTriggerForFireTime(conn, nextFireTime);
/* */
/* 1754 */ if (null != triggerKey)
/* */ {
/* 1756 */ int res = getDelegate().updateTriggerStateFromOtherState(conn, triggerKey.getName(), triggerKey.getGroup(), "ACQUIRED", "WAITING");
/* */
/* 1762 */ if (res > 0)
/* */ {
/* 1764 */ nextTrigger = retrieveTrigger(conn, ctxt, triggerKey.getName(), triggerKey.getGroup());
/* */
/* 1767 */ if (nextTrigger != null)
/* */ {
/* 1769 */ nextTrigger.setFireInstanceId(getFiredTriggerRecordId());
/* */
/* 1771 */ getDelegate().insertFiredTrigger(conn, nextTrigger, "ACQUIRED", null);
/* */
/* 1774 */ acquiredOne = true;
/* */ }
/* */ }
/* */ }
/* 1776 */ if (triggerKey == null) break;
/* 1776 */ }while (!acquiredOne);
/* */ } catch (Exception e) {
/* 1778 */ throw new JobPersistenceException("Couldn't acquire next trigger: " + e.getMessage(), e);
/* */ }
/* */ }
/* */
/* 1782 */ while (!acquiredOne);
/* */
/* 1784 */ return nextTrigger;
/* */ }
/* */
/* */ protected void releaseAcquiredTrigger(Connection conn, SchedulingContext ctxt, Trigger trigger) throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 1791 */ getDelegate().updateTriggerStateFromOtherState(conn, trigger.getName(), trigger.getGroup(), "WAITING", "ACQUIRED");
/* */
/* 1794 */ getDelegate().deleteFiredTrigger(conn, trigger.getFireInstanceId());
/* */ } catch (SQLException e) {
/* 1796 */ throw new JobPersistenceException("Couldn't release acquired trigger: " + e.getMessage(), e);
/* */ }
/* */ }
/* */
/* */ protected TriggerFiredBundle triggerFired(Connection conn, SchedulingContext ctxt, Trigger trigger)
/* */ throws JobPersistenceException
/* */ {
/* 1804 */ JobDetail job = null;
/* 1805 */ Calendar cal = null;
/* */ try
/* */ {
/* 1809 */ String state = getDelegate().selectTriggerState(conn, trigger.getName(), trigger.getGroup());
/* */
/* 1811 */ if (!state.equals("ACQUIRED")) return null;
/* */ }
/* */ catch (SQLException e) {
/* 1813 */ throw new JobPersistenceException("Couldn't select trigger state: " + e.getMessage(), e);
/* */ }
/* */
/* */ try
/* */ {
/* 1818 */ job = retrieveJob(conn, ctxt, trigger.getJobName(), trigger.getJobGroup());
/* */
/* 1820 */ if (job == null) return null;
/* */ }
/* */ catch (JobPersistenceException jpe) {
/* */ try {
/* 1823 */ getLog().error("Error retrieving job, setting trigger state to ERROR.", jpe);
/* 1824 */ getDelegate().updateTriggerState(conn, trigger.getName(), trigger.getGroup(), "ERROR");
/* */ }
/* */ catch (SQLException sqle) {
/* 1827 */ getLog().error("Unable to set trigger state to ERROR.", sqle);
/* */ }
/* 1829 */ throw jpe;
/* */ }
/* */
/* 1832 */ if (trigger.getCalendarName() != null) {
/* 1833 */ cal = retrieveCalendar(conn, ctxt, trigger.getCalendarName());
/* 1834 */ if (cal == null) return null;
/* */ }
/* */ try
/* */ {
/* 1838 */ getDelegate().deleteFiredTrigger(conn, trigger.getFireInstanceId());
/* 1839 */ getDelegate().insertFiredTrigger(conn, trigger, "EXECUTING", job);
/* */ }
/* */ catch (SQLException e) {
/* 1842 */ throw new JobPersistenceException("Couldn't insert fired trigger: " + e.getMessage(), e);
/* */ }
/* */
/* 1846 */ Date prevFireTime = trigger.getPreviousFireTime();
/* */
/* 1849 */ trigger.triggered(cal);
/* */
/* 1851 */ String state = "WAITING";
/* 1852 */ boolean force = true;
/* */
/* 1854 */ if (job.isStateful()) {
/* 1855 */ state = "BLOCKED";
/* 1856 */ force = false;
/* */ try {
/* 1858 */ getDelegate().updateTriggerStatesForJobFromOtherState(conn, job.getName(), job.getGroup(), "BLOCKED", "WAITING");
/* */
/* 1860 */ getDelegate().updateTriggerStatesForJobFromOtherState(conn, job.getName(), job.getGroup(), "BLOCKED", "ACQUIRED");
/* */
/* 1862 */ getDelegate().updateTriggerStatesForJobFromOtherState(conn, job.getName(), job.getGroup(), "PAUSED_BLOCKED", "PAUSED");
/* */ }
/* */ catch (SQLException e) {
/* 1865 */ throw new JobPersistenceException("Couldn't update states of blocked triggers: " + e.getMessage(), e);
/* */ }
/* */
/* */ }
/* */
/* 1871 */ if (trigger.getNextFireTime() == null) {
/* 1872 */ state = "COMPLETE";
/* 1873 */ force = true;
/* */ }
/* */
/* 1876 */ storeTrigger(conn, ctxt, trigger, job, true, state, force, false);
/* */
/* 1878 */ job.getJobDataMap().clearDirtyFlag();
/* */
/* 1880 */ return new TriggerFiredBundle(job, trigger, cal, trigger.getGroup().equals("RECOVERING_JOBS"), new Date(), trigger.getPreviousFireTime(), prevFireTime, trigger.getNextFireTime());
/* */ }
/* */
/* */ protected void triggeredJobComplete(Connection conn, SchedulingContext ctxt, Trigger trigger, JobDetail jobDetail, int triggerInstCode)
/* */ throws JobPersistenceException
/* */ {
/* */ try
/* */ {
/* 1889 */ if (triggerInstCode == 3) {
/* 1890 */ if (trigger.getNextFireTime() == null)
/* */ {
/* 1893 */ TriggerStatus stat = getDelegate().selectTriggerStatus(conn, trigger.getName(), trigger.getGroup());
/* */
/* 1895 */ if ((stat != null) && (stat.getNextFireTime() == null))
/* 1896 */ removeTrigger(conn, ctxt, trigger.getName(), trigger.getGroup());
/* */ }
/* */ else
/* */ {
/* 1900 */ removeTrigger(conn, ctxt, trigger.getName(), trigger.getGroup());
/* */ }
/* 1902 */ } else if (triggerInstCode == 2) {
/* 1903 */ getDelegate().updateTriggerState(conn, trigger.getName(), trigger.getGroup(), "COMPLETE");
/* */ }
/* 1905 */ else if (triggerInstCode == 5) {
/* 1906 */ getLog().info("Trigger " + trigger.getFullName() + " set to ERROR state.");
/* 1907 */ getDelegate().updateTriggerState(conn, trigger.getName(), trigger.getGroup(), "ERROR");
/* */ }
/* 1909 */ else if (triggerInstCode == 4) {
/* 1910 */ getDelegate().updateTriggerStatesForJob(conn, trigger.getJobName(), trigger.getJobGroup(), "COMPLETE");
/* */ }
/* 1913 */ else if (triggerInstCode == 6) {
/* 1914 */ getLog().info("All triggers of Job " + trigger.getFullJobName() + " set to ERROR state.");
/* */
/* 1916 */ getDelegate().updateTriggerStatesForJob(conn, trigger.getJobName(), trigger.getJobGroup(), "ERROR");
/* */ }
/* */
/* 1921 */ if (jobDetail.isStateful()) {
/* 1922 */ getDelegate().updateTriggerStatesForJobFromOtherState(conn, jobDetail.getName(), jobDetail.getGroup(), "WAITING", "BLOCKED");
/* */
/* 1926 */ getDelegate().updateTriggerStatesForJobFromOtherState(conn, jobDetail.getName(), jobDetail.getGroup(), "PAUSED", "PAUSED_BLOCKED");
/* */ try
/* */ {
/* 1931 */ if (jobDetail.getJobDataMap().isDirty())
/* 1932 */ getDelegate().updateJobData(conn, jobDetail);
/* */ }
/* */ catch (IOException e) {
/* 1935 */ throw new JobPersistenceException("Couldn't serialize job data: " + e.getMessage(), e);
/* */ }
/* */ catch (SQLException e) {
/* 1938 */ throw new JobPersistenceException("Couldn't update job data: " + e.getMessage(), e);
/* */ }
/* */ }
/* */ }
/* */ catch (SQLException e) {
/* 1943 */ throw new JobPersistenceException("Couldn't update trigger state(s): " + e.getMessage(), e);
/* */ }
/* */
/* */ try
/* */ {
/* 1948 */ getDelegate().deleteFiredTrigger(conn, trigger.getFireInstanceId());
/* */ } catch (SQLException e) {
/* 1950 */ throw new JobPersistenceException("Couldn't delete fired trigger: " + e.getMessage(), e);
/* */ }
/* */ }
/* */
/* */ protected DriverDelegate getDelegate()
/* */ throws NoSuchDelegateException
/* */ {
/* 1961 */ if (null == this.delegate) {
/* */ try {
/* 1963 */ if (this.delegateClassName != null) {
/* 1964 */ this.delegateClass = getClassLoadHelper().loadClass(this.delegateClassName);
/* */ }
/* */
/* 1967 */ Constructor ctor = null;
/* 1968 */ Object[] ctorParams = null;
/* 1969 */ if (canUseProperties()) {
/* 1970 */ Class[] ctorParamTypes = { Log.class, String.class, String.class, Boolean.class };
/* */
/* 1972 */ ctor = this.delegateClass.getConstructor(ctorParamTypes);
/* 1973 */ ctorParams = new Object[] { getLog(), this.tablePrefix, this.instanceId, new Boolean(canUseProperties()) };
/* */ }
/* */ else {
/* 1976 */ Class[] ctorParamTypes = { Log.class, String.class, String.class };
/* */
/* 1978 */ ctor = this.delegateClass.getConstructor(ctorParamTypes);
/* 1979 */ ctorParams = new Object[] { getLog(), this.tablePrefix, this.instanceId };
/* */ }
/* */
/* 1982 */ this.delegate = ((DriverDelegate)ctor.newInstance(ctorParams));
/* */ } catch (NoSuchMethodException e) {
/* 1984 */ throw new NoSuchDelegateException("Couldn't find delegate constructor: " + e.getMessage());
/* */ }
/* */ catch (InstantiationException e) {
/* 1987 */ throw new NoSuchDelegateException("Couldn't create delegate: " + e.getMessage());
/* */ }
/* */ catch (IllegalAccessException e) {
/* 1990 */ throw new NoSuchDelegateException("Couldn't create delegate: " + e.getMessage());
/* */ }
/* */ catch (InvocationTargetException e) {
/* 1993 */ throw new NoSuchDelegateException("Couldn't create delegate: " + e.getMessage());
/* */ }
/* */ catch (ClassNotFoundException e) {
/* 1996 */ throw new NoSuchDelegateException("Couldn't load delegate class: " + e.getMessage());
/* */ }
/* */
/* */ }
/* */
/* 2001 */ return this.delegate;
/* */ }
/* */
/* */ protected Semaphore getLockHandler() {
/* 2005 */ return this.lockHandler;
/* */ }
/* */
/* */ protected abstract boolean doRecoverMisfires()
/* */ throws JobPersistenceException;
/* */
/* */ protected void signalSchedulingChange()
/* */ {
/* 2016 */ this.signaler.signalSchedulingChange();
/* */ }
/* */
/* */ protected abstract boolean doCheckin()
/* */ throws JobPersistenceException;
/* */
/* */ protected List findFailedInstances(Connection conn)
/* */ throws JobPersistenceException
/* */ {
/* 2037 */ List failedInstances = new LinkedList();
/* 2038 */ boolean selfFailed = false;
/* */
/* 2040 */ long timeNow = System.currentTimeMillis();
/* */ try
/* */ {
/* 2043 */ List states = getDelegate().selectSchedulerStateRecords(conn, null);
/* */
/* 2045 */ HashMap statesById = new HashMap();
/* 2046 */ Iterator itr = states.iterator();
/* 2047 */ while (itr.hasNext()) {
/* 2048 */ SchedulerStateRecord rec = (SchedulerStateRecord)itr.next();
/* 2049 */ statesById.put(rec.getSchedulerInstanceId(), rec);
/* */ }
/* */
/* 2052 */ itr = states.iterator();
/* 2053 */ while (itr.hasNext()) {
/* 2054 */ SchedulerStateRecord rec = (SchedulerStateRecord)itr.next();
/* */
/* 2057 */ if (rec.getSchedulerInstanceId().equals(getInstanceId())) {
/* 2058 */ if (this.firstCheckIn) {
/* 2059 */ if (rec.getRecoverer() == null) {
/* 2060 */ failedInstances.add(rec);
/* */ }
/* */ else {
/* 2063 */ SchedulerStateRecord recOrec = (SchedulerStateRecord)statesById.get(rec.getRecoverer());
/* */
/* 2065 */ long failedIfAfter = recOrec == null ? timeNow : calcFailedIfAfter(recOrec);
/* */
/* 2068 */ if ((failedIfAfter < timeNow) || (recOrec == null)) {
/* 2069 */ failedInstances.add(rec);
/* */ }
/* */
/* */ }
/* */
/* */ }
/* */
/* */ }
/* */ else
/* */ {
/* 2079 */ long failedIfAfter = calcFailedIfAfter(rec);
/* */
/* 2081 */ if (rec.getRecoverer() == null) {
/* 2082 */ if (failedIfAfter < timeNow)
/* 2083 */ failedInstances.add(rec);
/* */ }
/* */ else
/* */ {
/* 2087 */ SchedulerStateRecord recOrec = (SchedulerStateRecord)statesById.get(rec.getRecoverer());
/* */
/* 2089 */ failedIfAfter = recOrec == null ? timeNow : calcFailedIfAfter(recOrec);
/* */
/* 2092 */ if ((failedIfAfter < timeNow) || (recOrec == null))
/* 2093 */ failedInstances.add(rec);
/* */ }
/* */ }
/* */ }
/* */ }
/* */ catch (Exception e) {
/* 2099 */ this.lastCheckin = System.currentTimeMillis();
/* 2100 */ throw new JobPersistenceException("Failure identifying failed instances when checking-in: " + e.getMessage(), e);
/* */ }
/* */
/* 2104 */ return failedInstances;
/* */ }
/* */
/* */ protected long calcFailedIfAfter(SchedulerStateRecord rec) {
/* 2108 */ return rec.getCheckinTimestamp() + Math.max(rec.getCheckinInterval(), System.currentTimeMillis() - this.lastCheckin) + 7500L;
/* */ }
/* */
/* */ protected List clusterCheckIn(Connection conn)
/* */ throws JobPersistenceException
/* */ {
/* 2117 */ List failedInstances = findFailedInstances(conn);
/* */ try
/* */ {
/* 2123 */ this.lastCheckin = System.currentTimeMillis();
/* 2124 */ if (getDelegate().updateSchedulerState(conn, getInstanceId(), this.lastCheckin, null) == 0) {
/* 2125 */ getDelegate().insertSchedulerState(conn, getInstanceId(), this.lastCheckin, getClusterCheckinInterval(), null);
/* */ }
/* */ }
/* */ catch (Exception e)
/* */ {
/* 2130 */ throw new JobPersistenceException("Failure updating scheduler state when checking-in: " + e.getMessage(), e);
/* */ }
/* */
/* 2134 */ return failedInstances;
/* */ }
/* */
/* */ protected void clusterRecover(Connection conn, List failedInstances)
/* */ throws JobPersistenceException
/* */ {
/* 2140 */ if (failedInstances.size() > 0)
/* */ {
/* 2142 */ long recoverIds = System.currentTimeMillis();
/* */
/* 2144 */ logWarnIfNonZero(failedInstances.size(), "ClusterManager: detected " + failedInstances.size() + " failed or restarted instances.");
/* */ try
/* */ {
/* 2148 */ Iterator itr = failedInstances.iterator();
/* 2149 */ while (itr.hasNext()) {
/* 2150 */ SchedulerStateRecord rec = (SchedulerStateRecord)itr.next();
/* */
/* 2153 */ getLog().info("ClusterManager: Scanning for instance \"" + rec.getSchedulerInstanceId() + "\"'s failed in-progress jobs.");
/* */
/* 2158 */ List firedTriggerRecs = getDelegate().selectInstancesFiredTriggerRecords(conn, rec.getSchedulerInstanceId());
/* */
/* 2162 */ int acquiredCount = 0;
/* 2163 */ int recoveredCount = 0;
/* 2164 */ int otherCount = 0;
/* */
/* 2166 */ Iterator ftItr = firedTriggerRecs.iterator();
/* 2167 */ while (ftItr.hasNext()) {
/* 2168 */ FiredTriggerRecord ftRec = (FiredTriggerRecord)ftItr.next();
/* */
/* 2171 */ Key tKey = ftRec.getTriggerKey();
/* 2172 */ Key jKey = ftRec.getJobKey();
/* */
/* 2175 */ if (ftRec.getFireInstanceState().equals("BLOCKED")) {
/* 2176 */ getDelegate().updateTriggerStatesForJobFromOtherState(conn, jKey.getName(), jKey.getGroup(), "WAITING", "BLOCKED");
/* */ }
/* */
/* 2182 */ if (ftRec.getFireInstanceState().equals("PAUSED_BLOCKED")) {
/* 2183 */ getDelegate().updateTriggerStatesForJobFromOtherState(conn, jKey.getName(), jKey.getGroup(), "PAUSED", "PAUSED_BLOCKED");
/* */ }
/* */
/* 2191 */ if (ftRec.getFireInstanceState().equals("ACQUIRED")) {
/* 2192 */ getDelegate().updateTriggerStateFromOtherState(conn, tKey.getName(), tKey.getGroup(), "WAITING", "ACQUIRED");
/* */
/* 2195 */ acquiredCount++;
/* */ }
/* 2198 */ else if (ftRec.isJobRequestsRecovery()) {
/* 2199 */ if (jobExists(conn, jKey.getName(), jKey.getGroup())) {
/* 2200 */ SimpleTrigger rcvryTrig = new SimpleTrigger("recover_" + rec.getSchedulerInstanceId() + "_" + String.valueOf(recoverIds++), "RECOVERING_JOBS", new Date(ftRec.getFireTimestamp()));
/* */
/* 2207 */ rcvryTrig.setJobName(jKey.getName());
/* 2208 */ rcvryTrig.setJobGroup(jKey.getGroup());
/* 2209 */ rcvryTrig.setMisfireInstruction(1);
/* */
/* 2211 */ JobDataMap jd = getDelegate().selectTriggerJobDataMap(conn, tKey.getName(), tKey.getGroup());
/* 2212 */ jd.put("QRTZ_FAILED_JOB_ORIG_TRIGGER_NAME", tKey.getName());
/* 2213 */ jd.put("QRTZ_FAILED_JOB_ORIG_TRIGGER_GROUP", tKey.getGroup());
/* 2214 */ jd.put("QRTZ_FAILED_JOB_ORIG_TRIGGER_FIRETIME_IN_MILLISECONDS_AS_STRING", String.valueOf(ftRec.getFireTimestamp()));
/* 2215 */ rcvryTrig.setJobDataMap(jd);
/* */
/* 2217 */ rcvryTrig.computeFirstFireTime(null);
/* 2218 */ storeTrigger(conn, null, rcvryTrig, null, false, "WAITING", false, true);
/* */
/* 2220 */ recoveredCount++;
/* */ } else {
/* 2222 */ getLog().warn("ClusterManager: failed job '" + jKey + "' no longer exists, cannot schedule recovery.");
/* */
/* 2227 */ otherCount++;
/* */ }
/* */ } else {
/* 2230 */ otherCount++;
/* */ }
/* */
/* 2234 */ if (ftRec.isJobIsStateful()) {
/* 2235 */ getDelegate().updateTriggerStatesForJobFromOtherState(conn, jKey.getName(), jKey.getGroup(), "WAITING", "BLOCKED");
/* */
/* 2240 */ getDelegate().updateTriggerStatesForJobFromOtherState(conn, jKey.getName(), jKey.getGroup(), "PAUSED", "PAUSED_BLOCKED");
/* */ }
/* */
/* */ }
/* */
/* 2248 */ getDelegate().deleteFiredTriggers(conn, rec.getSchedulerInstanceId());
/* */
/* 2251 */ logWarnIfNonZero(acquiredCount, "ClusterManager: ......Freed " + acquiredCount + " acquired trigger(s).");
/* */
/* 2254 */ logWarnIfNonZero(recoveredCount, "ClusterManager: ......Scheduled " + recoveredCount + " recoverable job(s) for recovery.");
/* */
/* 2257 */ logWarnIfNonZero(otherCount, "ClusterManager: ......Cleaned-up " + otherCount + " other failed job(s).");
/* */
/* 2261 */ getDelegate().deleteSchedulerState(conn, rec.getSchedulerInstanceId());
/* */
/* 2265 */ if (rec.getSchedulerInstanceId().equals(getInstanceId())) {
/* 2266 */ getDelegate().insertSchedulerState(conn, rec.getSchedulerInstanceId(), System.currentTimeMillis(), rec.getCheckinInterval(), null);
/* */ }
/* */ }
/* */
/* */ }
/* */ catch (Exception e)
/* */ {
/* 2273 */ throw new JobPersistenceException("Failure recovering jobs: " + e.getMessage(), e);
/* */ }
/* */ }
/* */ }
/* */
/* */ protected void logWarnIfNonZero(int val, String warning)
/* */ {
/* 2280 */ if (val > 0) getLog().info(warning);
/* */ else
/* 2282 */ getLog().debug(warning);
/* */ }
/* */
/* */ protected void closeConnection(Connection conn)
/* */ throws JobPersistenceException
/* */ {
/* 2295 */ if (conn != null)
/* */ try {
/* 2297 */ conn.close();
/* */ } catch (SQLException e) {
/* 2299 */ throw new JobPersistenceException("Couldn't close jdbc connection. " + e.getMessage(), e);
/* */ }
/* */ }
/* */
/* */ protected void rollbackConnection(Connection conn)
/* */ throws JobPersistenceException
/* */ {
/* 2315 */ if (conn != null)
/* */ try {
/* 2317 */ conn.rollback();
/* */ } catch (SQLException e) {
/* 2319 */ throw new JobPersistenceException("Couldn't rollback jdbc connection. " + e.getMessage(), e);
/* */ }
/* */ }
/* */
/* */ protected void commitConnection(Connection conn)
/* */ throws JobPersistenceException
/* */ {
/* 2334 */ if (conn != null)
/* */ try {
/* 2336 */ conn.commit();
/* */ } catch (SQLException e) {
/* 2338 */ throw new JobPersistenceException("Couldn't commit jdbc connection. " + e.getMessage(), e);
/* */ }
/* */ }
/* */
/* */ class MisfireHandler extends Thread
/* */ {
/* 2423 */ private boolean shutdown = false;
/* */ private JobStoreSupport js;
/* 2427 */ private int numFails = 0;
/* */
/* */ MisfireHandler(JobStoreSupport js)
/* */ {
/* 2431 */ this.js = js;
/* 2432 */ setName("QuartzScheduler_" + JobStoreSupport.this.instanceName + "-" + JobStoreSupport.this.instanceId + "_MisfireHandler");
/* */ }
/* */
/* */ public void initialize()
/* */ {
/* 2437 */ start();
/* */ }
/* */
/* */ public void shutdown() {
/* 2441 */ this.shutdown = true;
/* 2442 */ interrupt();
/* */ }
/* */
/* */ private boolean manage() {
/* */ try {
/* 2447 */ JobStoreSupport.this.getLog().debug("MisfireHandler: scanning for misfires...");
/* */
/* 2449 */ boolean res = this.js.doRecoverMisfires();
/* 2450 */ this.numFails = 0;
/* 2451 */ return res;
/* */ } catch (Exception e) {
/* 2453 */ if (this.numFails % 4 == 0) {
/* 2454 */ JobStoreSupport.this.getLog().error("MisfireHandler: Error handling misfires: " + e.getMessage(), e);
/* */ }
/* */
/* 2457 */ this.numFails += 1;
/* */ }
/* 2459 */ return false;
/* */ }
/* */
/* */ public void run()
/* */ {
/* 2464 */ while (!this.shutdown)
/* */ {
/* 2466 */ long sTime = System.currentTimeMillis();
/* */
/* 2468 */ boolean moreToDo = manage();
/* */
/* 2470 */ if (JobStoreSupport.this.lastRecoverCount > 0) JobStoreSupport.this.signalSchedulingChange();
/* */
/* 2472 */ long spanTime = System.currentTimeMillis() - sTime;
/* */
/* 2474 */ if ((!this.shutdown) && (!moreToDo)) {
/* 2475 */ long timeToSleep = JobStoreSupport.this.getMisfireThreshold() - spanTime;
/* 2476 */ if (timeToSleep <= 0L) timeToSleep = 50L;
/* */
/* 2478 */ if (this.numFails > 0) timeToSleep = Math.max(JobStoreSupport.this.getDbRetryInterval(), timeToSleep);
/* */
/* 2480 */ if (timeToSleep > 0L) try {
/* 2481 */ Thread.sleep(timeToSleep);
/* */ }
/* */ catch (Exception ignore) {
/* */ }
/* */ }
/* 2485 */ else if (moreToDo) {
/* */ try {
/* 2487 */ Thread.sleep(50L);
/* */ }
/* */ catch (Exception ignore)
/* */ {
/* */ }
/* */ }
/* */ }
/* */ }
/* */ }
/* */
/* */ class ClusterManager extends Thread
/* */ {
/* 2352 */ private boolean shutdown = false;
/* */ private JobStoreSupport js;
/* 2356 */ private int numFails = 0;
/* */
/* */ ClusterManager(JobStoreSupport js) {
/* 2359 */ this.js = js;
/* 2360 */ setPriority(7);
/* 2361 */ setName("QuartzScheduler_" + JobStoreSupport.this.instanceName + "-" + JobStoreSupport.this.instanceId + "_ClusterManager");
/* */ }
/* */
/* */ public void initialize() {
/* 2365 */ manage();
/* 2366 */ start();
/* */ }
/* */
/* */ public void shutdown() {
/* 2370 */ this.shutdown = true;
/* 2371 */ interrupt();
/* */ }
/* */
/* */ private boolean manage() {
/* 2375 */ boolean res = false;
/* */ try
/* */ {
/* 2378 */ res = this.js.doCheckin();
/* */
/* 2380 */ this.numFails = 0;
/* 2381 */ JobStoreSupport.this.getLog().debug("ClusterManager: Check-in complete.");
/* */ } catch (Exception e) {
/* 2383 */ if (this.numFails % 4 == 0) {
/* 2384 */ JobStoreSupport.this.getLog().error("ClusterManager: Error managing cluster: " + e.getMessage(), e);
/* */ }
/* */
/* 2387 */ this.numFails += 1;
/* */ }
/* 2389 */ return res;
/* */ }
/* */
/* */ public void run() {
/* 2393 */ while (!this.shutdown)
/* */ {
/* 2395 */ if (!this.shutdown) {
/* 2396 */ long timeToSleep = JobStoreSupport.this.getClusterCheckinInterval();
/* 2397 */ long transpiredTime = System.currentTimeMillis() - JobStoreSupport.this.lastCheckin;
/* 2398 */ timeToSleep -= transpiredTime;
/* 2399 */ if (timeToSleep <= 0L) timeToSleep = 100L;
/* */
/* 2401 */ if (this.numFails > 0) timeToSleep = Math.max(JobStoreSupport.this.getDbRetryInterval(), timeToSleep);
/* */ try
/* */ {
/* 2404 */ Thread.sleep(timeToSleep);
/* */ }
/* */ catch (Exception ignore) {
/* */ }
/* */ }
/* 2409 */ if ((this.shutdown) || (!manage())) continue; JobStoreSupport.this.signalSchedulingChange();
/* */ }
/* */ }
/* */ }
/* */ }
/* Location: /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/thirdparty-all.jar
* Qualified Name: org.quartz.impl.jdbcjobstore.JobStoreSupport
* JD-Core Version: 0.6.0
*/