Quartz JobRunShell實現

Class Diagram.png

quartz中,Job接口是要實現execute方法的.JobRunShell run方法會實例化job實現類,然后調用execute.run方法中也會有捕獲異常,以及捕獲異常如何處理的機制.
那么JobRunShell是通過JobExecutionException來判斷是要重試執行,還是不在重試.

JobRunShell run實現

qs.addInternalSchedulerListener(this);
try {
    OperableTrigger trigger = (OperableTrigger) jec.getTrigger();
    JobDetail jobDetail = jec.getJobDetail();
    do {
        JobExecutionException jobExEx = null;
        Job job = jec.getJobInstance();
        try {
            begin();
        } catch (SchedulerException se) {
            qs.notifySchedulerListenersError("Error executing Job ("
                    + jec.getJobDetail().getKey()
                    + ": couldn't begin execution.", se);
            break;
        }
        // notify job & trigger listeners...
        try {
            if (!notifyListenersBeginning(jec)) {
                break;
            }
        } catch(VetoedException ve) {
            try {
                CompletedExecutionInstruction instCode = trigger.executionComplete(jec, null);
                qs.notifyJobStoreJobVetoed(trigger, jobDetail, instCode);
                 
                // QTZ-205
                // Even if trigger got vetoed, we still needs to check to see if it's the trigger's finalized run or not.
                if (jec.getTrigger().getNextFireTime() == null) {
                    qs.notifySchedulerListenersFinalized(jec.getTrigger());
                }
 
                complete(true);
            } catch (SchedulerException se) {
                qs.notifySchedulerListenersError("Error during veto of Job ("
                        + jec.getJobDetail().getKey()
                        + ": couldn't finalize execution.", se);
            }
            break;
        }
 
        long startTime = System.currentTimeMillis();
        long endTime = startTime;
 
        // execute the job
        try {
            log.debug("Calling execute on job " + jobDetail.getKey());
            job.execute(jec);//執行jobexecute
            endTime = System.currentTimeMillis();
        } catch (JobExecutionException jee) {//如果execute拋出異常,并且是JobExecutionException,JobExecutionException會保存著是重試,還是結束的信息
            endTime = System.currentTimeMillis();
            jobExEx = jee;
            getLog().info("Job " + jobDetail.getKey() +
                    " threw a JobExecutionException: ", jobExEx);
        } catch (Throwable e) { //execute拋出異常
            endTime = System.currentTimeMillis();
            getLog().error("Job " + jobDetail.getKey() +
                    " threw an unhandled Exception: ", e);
            SchedulerException se = new SchedulerException(
                    "Job threw an unhandled exception.", e);
            qs.notifySchedulerListenersError("Job ("
                    + jec.getJobDetail().getKey()
                    + " threw an exception.", se);
            jobExEx = new JobExecutionException(se, false);
        }
        jec.setJobRunTime(endTime - startTime);
        // notify all job listeners
        if (!notifyJobListenersComplete(jec, jobExEx)) {
            break;
        }
        CompletedExecutionInstruction instCode = CompletedExecutionInstruction.NOOP;
 
        // update the trigger
        try {
            instCode = trigger.executionComplete(jec, jobExEx);
        } catch (Exception e) {
            // If this happens, there's a bug in the trigger...
            SchedulerException se = new SchedulerException(
                    "Trigger threw an unhandled exception.", e);
            qs.notifySchedulerListenersError(
                    "Please report this error to the Quartz developers.",
                    se);
        }
        // notify all trigger listeners
        if (!notifyTriggerListenersComplete(jec, instCode)) {
            break;
        }
        // update job/trigger or re-execute job
        if (instCode == CompletedExecutionInstruction.RE_EXECUTE_JOB) {//如果在execute設置的是重復執行,那么會重新執行run函數
            jec.incrementRefireCount();
            try {
                complete(false);
            } catch (SchedulerException se) {
                qs.notifySchedulerListenersError("Error executing Job ("
                        + jec.getJobDetail().getKey()
                        + ": couldn't finalize execution.", se);
            }
            continue;
        }
        try {
            complete(true);
        } catch (SchedulerException se) {
            qs.notifySchedulerListenersError("Error executing Job ("
                    + jec.getJobDetail().getKey()
                    + ": couldn't finalize execution.", se);
            continue;
        }
        qs.notifyJobStoreJobComplete(trigger, jobDetail, instCode);
        break;
    } while (true);
 
} finally {
    qs.removeInternalSchedulerListener(this);
}

自定義retry次數job實現

class MyRetryJob  extends  Job{
  override def execute(context: JobExecutionContext): Unit = {
    val dataMap = context.getMergedJobDataMap
    val retry = dataMap.getInt("retry")
    var retryCount = dataMap.getOrDefault("retryCount",new Integer(1)).asInstanceOf[Integer]

    try{
        println("exec "+(retryCount))
        retryCount = retryCount+1

        dataMap.put("retryCount",retryCount)
        throw new Exception("just for test exception")
    }catch {
      case e:Exception=>
        val execError = new JobExecutionException(e)
        if(retryCount<=retry){
          execError.setRefireImmediately(true)
        }
        else{
          execError.setUnscheduleAllTriggers(true)
        }
        throw  execError
    }

  }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,948評論 18 139
  • ** 版本:2.2.1 ** Hello world: 調度器: 任務詳情:任務體實現Job接口 觸發器: 執行調...
    Coselding閱讀 10,255評論 12 38
  • scheduler定時調度系統是大多行業項目都需要的,傳統的spring-job模式,個人感覺已經out了,因為存...
    安琪拉_4b7e閱讀 2,864評論 4 6
  • 飯后在大坪繞圈子。明明是從英利國際旁的小道進去的,從小道出來應該是到永輝超市,可在一條道分岔后,我就沿著街邊擺滿...
    凝固的火閱讀 158評論 0 0
  • 仿阿爾謝尼的詩 (照片攝于去車站的路上) El nino 來的前一天 金色陽光照著木板上的水壺 午后,風推開了門 ...
    小狐仙妮妮閱讀 312評論 0 0