use of org.quartz.JobPersistenceException in project weicoder by wdcode.
the class JobStoreSupport method recoverJobs.
/**
* <p>
* Will recover any failed or misfired jobs and clean up the data store as appropriate.
* </p>
*
* @throws JobPersistenceException if jobs could not be recovered
*/
protected void recoverJobs(Connection conn) throws JobPersistenceException {
try {
// update inconsistent job states
int rows = getDelegate().updateTriggerStatesFromOtherStates(conn, STATE_WAITING, STATE_ACQUIRED, STATE_BLOCKED);
rows += getDelegate().updateTriggerStatesFromOtherStates(conn, STATE_PAUSED, STATE_PAUSED_BLOCKED, STATE_PAUSED_BLOCKED);
getLog().info("Freed " + rows + " triggers from 'acquired' / 'blocked' state.");
// clean up misfired jobs
recoverMisfiredJobs(conn, true);
// recover jobs marked for recovery that were not fully executed
List<OperableTrigger> recoveringJobTriggers = getDelegate().selectTriggersForRecoveringJobs(conn);
getLog().info("Recovering " + recoveringJobTriggers.size() + " jobs that were in-progress at the time of the last shut-down.");
for (OperableTrigger recoveringJobTrigger : recoveringJobTriggers) {
if (jobExists(conn, recoveringJobTrigger.getJobKey())) {
recoveringJobTrigger.computeFirstFireTime(null);
storeTrigger(conn, recoveringJobTrigger, null, false, STATE_WAITING, false, true);
}
}
getLog().info("Recovery complete.");
// remove lingering 'complete' triggers...
List<TriggerKey> cts = getDelegate().selectTriggersInState(conn, STATE_COMPLETE);
for (TriggerKey ct : cts) {
removeTrigger(conn, ct);
}
getLog().info("Removed " + cts.size() + " 'complete' triggers.");
// clean up any fired trigger entries
int n = getDelegate().deleteFiredTriggers(conn);
getLog().info("Removed " + n + " stale fired job entries.");
} catch (JobPersistenceException e) {
throw e;
} catch (Exception e) {
throw new JobPersistenceException("Couldn't recover jobs: " + e.getMessage(), e);
}
}
use of org.quartz.JobPersistenceException in project weicoder by wdcode.
the class JobStoreSupport method clusterRecover.
protected void clusterRecover(Connection conn, List<SchedulerStateRecord> failedInstances) throws JobPersistenceException {
if (failedInstances.size() > 0) {
long recoverIds = System.currentTimeMillis();
logWarnIfNonZero(failedInstances.size(), "ClusterManager: detected " + failedInstances.size() + " failed or restarted instances.");
try {
for (SchedulerStateRecord rec : failedInstances) {
getLog().info("ClusterManager: Scanning for instance \"" + rec.getSchedulerInstanceId() + "\"'s failed in-progress jobs.");
List<FiredTriggerRecord> firedTriggerRecs = getDelegate().selectInstancesFiredTriggerRecords(conn, rec.getSchedulerInstanceId());
int acquiredCount = 0;
int recoveredCount = 0;
int otherCount = 0;
Set<TriggerKey> triggerKeys = new HashSet<TriggerKey>();
for (FiredTriggerRecord ftRec : firedTriggerRecs) {
TriggerKey tKey = ftRec.getTriggerKey();
JobKey jKey = ftRec.getJobKey();
triggerKeys.add(tKey);
// release blocked triggers..
if (ftRec.getFireInstanceState().equals(STATE_BLOCKED)) {
getDelegate().updateTriggerStatesForJobFromOtherState(conn, jKey, STATE_WAITING, STATE_BLOCKED);
} else if (ftRec.getFireInstanceState().equals(STATE_PAUSED_BLOCKED)) {
getDelegate().updateTriggerStatesForJobFromOtherState(conn, jKey, STATE_PAUSED, STATE_PAUSED_BLOCKED);
}
// release acquired triggers..
if (ftRec.getFireInstanceState().equals(STATE_ACQUIRED)) {
getDelegate().updateTriggerStateFromOtherState(conn, tKey, STATE_WAITING, STATE_ACQUIRED);
acquiredCount++;
} else if (ftRec.isJobRequestsRecovery()) {
// executed..
if (jobExists(conn, jKey)) {
@SuppressWarnings("deprecation") SimpleTriggerImpl rcvryTrig = new SimpleTriggerImpl("recover_" + rec.getSchedulerInstanceId() + "_" + String.valueOf(recoverIds++), Scheduler.DEFAULT_RECOVERY_GROUP, new Date(ftRec.getScheduleTimestamp()));
rcvryTrig.setJobName(jKey.getName());
rcvryTrig.setJobGroup(jKey.getGroup());
rcvryTrig.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY);
rcvryTrig.setPriority(ftRec.getPriority());
JobDataMap jd = getDelegate().selectTriggerJobDataMap(conn, tKey.getName(), tKey.getGroup());
jd.put(Scheduler.FAILED_JOB_ORIGINAL_TRIGGER_NAME, tKey.getName());
jd.put(Scheduler.FAILED_JOB_ORIGINAL_TRIGGER_GROUP, tKey.getGroup());
jd.put(Scheduler.FAILED_JOB_ORIGINAL_TRIGGER_FIRETIME_IN_MILLISECONDS, String.valueOf(ftRec.getFireTimestamp()));
jd.put(Scheduler.FAILED_JOB_ORIGINAL_TRIGGER_SCHEDULED_FIRETIME_IN_MILLISECONDS, String.valueOf(ftRec.getScheduleTimestamp()));
rcvryTrig.setJobDataMap(jd);
rcvryTrig.computeFirstFireTime(null);
storeTrigger(conn, rcvryTrig, null, false, STATE_WAITING, false, true);
recoveredCount++;
} else {
getLog().warn("ClusterManager: failed job '" + jKey + "' no longer exists, cannot schedule recovery.");
otherCount++;
}
} else {
otherCount++;
}
// free up stateful job's triggers
if (ftRec.isJobDisallowsConcurrentExecution()) {
getDelegate().updateTriggerStatesForJobFromOtherState(conn, jKey, STATE_WAITING, STATE_BLOCKED);
getDelegate().updateTriggerStatesForJobFromOtherState(conn, jKey, STATE_PAUSED, STATE_PAUSED_BLOCKED);
}
}
getDelegate().deleteFiredTriggers(conn, rec.getSchedulerInstanceId());
// Check if any of the fired triggers we just deleted were the last fired trigger
// records of a COMPLETE trigger.
int completeCount = 0;
for (TriggerKey triggerKey : triggerKeys) {
if (getDelegate().selectTriggerState(conn, triggerKey).equals(STATE_COMPLETE)) {
List<FiredTriggerRecord> firedTriggers = getDelegate().selectFiredTriggerRecords(conn, triggerKey.getName(), triggerKey.getGroup());
if (firedTriggers.isEmpty()) {
if (removeTrigger(conn, triggerKey)) {
completeCount++;
}
}
}
}
logWarnIfNonZero(acquiredCount, "ClusterManager: ......Freed " + acquiredCount + " acquired trigger(s).");
logWarnIfNonZero(completeCount, "ClusterManager: ......Deleted " + completeCount + " complete triggers(s).");
logWarnIfNonZero(recoveredCount, "ClusterManager: ......Scheduled " + recoveredCount + " recoverable job(s) for recovery.");
logWarnIfNonZero(otherCount, "ClusterManager: ......Cleaned-up " + otherCount + " other failed job(s).");
if (!rec.getSchedulerInstanceId().equals(getInstanceId())) {
getDelegate().deleteSchedulerState(conn, rec.getSchedulerInstanceId());
}
}
} catch (Throwable e) {
throw new JobPersistenceException("Failure recovering jobs: " + e.getMessage(), e);
}
}
}
use of org.quartz.JobPersistenceException in project weicoder by wdcode.
the class JobStoreSupport method replaceTrigger.
protected boolean replaceTrigger(Connection conn, TriggerKey key, OperableTrigger newTrigger) throws JobPersistenceException {
try {
// this must be called before we delete the trigger, obviously
JobDetail job = getDelegate().selectJobForTrigger(conn, getClassLoadHelper(), key);
if (job == null) {
return false;
}
if (!newTrigger.getJobKey().equals(job.getKey())) {
throw new JobPersistenceException("New trigger is not related to the same job as the old trigger.");
}
boolean removedTrigger = deleteTriggerAndChildren(conn, key);
storeTrigger(conn, newTrigger, job, false, STATE_WAITING, false, false);
return removedTrigger;
} catch (ClassNotFoundException e) {
throw new JobPersistenceException("Couldn't remove trigger: " + e.getMessage(), e);
} catch (SQLException e) {
throw new JobPersistenceException("Couldn't remove trigger: " + e.getMessage(), e);
}
}
use of org.quartz.JobPersistenceException in project weicoder by wdcode.
the class JobStoreSupport method findFailedInstances.
/**
* Get a list of all scheduler instances in the cluster that may have failed. This includes this scheduler if it is
* checking in for the first time.
*/
protected List<SchedulerStateRecord> findFailedInstances(Connection conn) throws JobPersistenceException {
try {
List<SchedulerStateRecord> failedInstances = new LinkedList<SchedulerStateRecord>();
boolean foundThisScheduler = false;
long timeNow = System.currentTimeMillis();
List<SchedulerStateRecord> states = getDelegate().selectSchedulerStateRecords(conn, null);
for (SchedulerStateRecord rec : states) {
// find own record...
if (rec.getSchedulerInstanceId().equals(getInstanceId())) {
foundThisScheduler = true;
if (firstCheckIn) {
failedInstances.add(rec);
}
} else {
// find failed instances...
if (calcFailedIfAfter(rec) < timeNow) {
failedInstances.add(rec);
}
}
}
// The first time through, also check for orphaned fired triggers.
if (firstCheckIn) {
failedInstances.addAll(findOrphanedFailedInstances(conn, states));
}
// Someone must have done recovery for us.
if ((!foundThisScheduler) && (!firstCheckIn)) {
// FUTURE_TODO: revisit when handle self-failed-out impl'ed (see FUTURE_TODO in clusterCheckIn() below)
getLog().warn("This scheduler instance (" + getInstanceId() + ") is still " + "active but was recovered by another instance in the cluster. " + "This may cause inconsistent behavior.");
}
return failedInstances;
} catch (Exception e) {
lastCheckin = System.currentTimeMillis();
throw new JobPersistenceException("Failure identifying failed instances when checking-in: " + e.getMessage(), e);
}
}
use of org.quartz.JobPersistenceException in project weicoder by wdcode.
the class JobStoreSupport method triggeredJobComplete.
protected void triggeredJobComplete(Connection conn, OperableTrigger trigger, JobDetail jobDetail, CompletedExecutionInstruction triggerInstCode) throws JobPersistenceException {
try {
if (triggerInstCode == CompletedExecutionInstruction.DELETE_TRIGGER) {
if (trigger.getNextFireTime() == null) {
// double check for possible reschedule within job
// execution, which would cancel the need to delete...
TriggerStatus stat = getDelegate().selectTriggerStatus(conn, trigger.getKey());
if (stat != null && stat.getNextFireTime() == null) {
removeTrigger(conn, trigger.getKey());
}
} else {
removeTrigger(conn, trigger.getKey());
signalSchedulingChangeOnTxCompletion(0L);
}
} else if (triggerInstCode == CompletedExecutionInstruction.SET_TRIGGER_COMPLETE) {
getDelegate().updateTriggerState(conn, trigger.getKey(), STATE_COMPLETE);
signalSchedulingChangeOnTxCompletion(0L);
} else if (triggerInstCode == CompletedExecutionInstruction.SET_TRIGGER_ERROR) {
getLog().info("Trigger " + trigger.getKey() + " set to ERROR state.");
getDelegate().updateTriggerState(conn, trigger.getKey(), STATE_ERROR);
signalSchedulingChangeOnTxCompletion(0L);
} else if (triggerInstCode == CompletedExecutionInstruction.SET_ALL_JOB_TRIGGERS_COMPLETE) {
getDelegate().updateTriggerStatesForJob(conn, trigger.getJobKey(), STATE_COMPLETE);
signalSchedulingChangeOnTxCompletion(0L);
} else if (triggerInstCode == CompletedExecutionInstruction.SET_ALL_JOB_TRIGGERS_ERROR) {
getLog().info("All triggers of Job " + trigger.getKey() + " set to ERROR state.");
getDelegate().updateTriggerStatesForJob(conn, trigger.getJobKey(), STATE_ERROR);
signalSchedulingChangeOnTxCompletion(0L);
}
if (jobDetail.isConcurrentExectionDisallowed()) {
getDelegate().updateTriggerStatesForJobFromOtherState(conn, jobDetail.getKey(), STATE_WAITING, STATE_BLOCKED);
getDelegate().updateTriggerStatesForJobFromOtherState(conn, jobDetail.getKey(), STATE_PAUSED, STATE_PAUSED_BLOCKED);
signalSchedulingChangeOnTxCompletion(0L);
}
if (jobDetail.isPersistJobDataAfterExecution()) {
try {
if (jobDetail.getJobDataMap().isDirty()) {
getDelegate().updateJobData(conn, jobDetail);
}
} catch (IOException e) {
throw new JobPersistenceException("Couldn't serialize job data: " + e.getMessage(), e);
} catch (SQLException e) {
throw new JobPersistenceException("Couldn't update job data: " + e.getMessage(), e);
}
}
} catch (SQLException e) {
throw new JobPersistenceException("Couldn't update trigger state(s): " + e.getMessage(), e);
}
try {
getDelegate().deleteFiredTrigger(conn, trigger.getFireInstanceId());
} catch (SQLException e) {
throw new JobPersistenceException("Couldn't delete fired trigger: " + e.getMessage(), e);
}
}
Aggregations