public Task GetWork(IJob job) { Task task; try { task = job.Execute(); } catch (Exception e) { QuietLog.LogHandledException(e); return new Task(() => {}); // returning dummy task so the job scheduler doesn't see errors } // wrapping the task inside an outer task which will continue with an error handler. return CreateWrappingContinuingTask(task, t => { if (t.IsCanceled) { Debug.WriteLine("Background Task Canceled: " + job.GetType()); } else if (t.IsFaulted) { Debug.WriteLine("Background Task Faulted: " + job.GetType()); QuietLog.LogHandledException(task.Exception); } // else happiness }, TaskContinuationOptions.ExecuteSynchronously); }
public async Task Execute(IJob job) { var source = new CancellationTokenSource(_timeout); var cancellation = new CancellationToken(); var task = Task.Factory.StartNew(() => job.Execute(source.Token), source.Token); var timeout = Task.Delay(_timeout, cancellation); if (await Task.WhenAny(task, timeout) == task) { await task; } else { var marker = new TaskCompletionSource<object>(); marker.SetException(new TimeoutException("Timed out after " + _timeout)); await marker.Task; } }
// Returns a task with the work to do if work is available to do and another web server // in the web farm isn't already doing it. public Task GetWork(IJob job) { if (job == null) { throw new ArgumentNullException("job"); } var unitOfWork = ReserveWork(WebServerWorkerId, job); if (unitOfWork == null) { return null; } Task task = null; try { task = job.Execute(); } catch (Exception e) { task = new Task(() => { throw e; }); } task.ContinueWith(c => { if (c.IsFaulted) { unitOfWork.Fail(c.Exception.GetBaseException()); } else { unitOfWork.Complete(); } }); return task; }
public Task GetWork(IJob job) { return job.Execute(); }
/// <summary> /// This method has to be implemented in order that starting of the thread causes the object's /// run method to be called in that separately executing thread. /// </summary> public virtual void Run() { qs.AddInternalSchedulerListener(this); try { IOperableTrigger trigger = (IOperableTrigger)jec.Trigger; IJobDetail jobDetail = jec.JobDetail; do { JobExecutionException jobExEx = null; IJob job = jec.JobInstance; try { Begin(); } catch (SchedulerException se) { qs.NotifySchedulerListenersError( string.Format(CultureInfo.InvariantCulture, "Error executing Job {0}: couldn't begin execution.", jec.JobDetail.Key), se); break; } // notify job & trigger listeners... SchedulerInstruction instCode; try { if (!NotifyListenersBeginning(jec)) { break; } } catch (VetoedException) { try { instCode = trigger.ExecutionComplete(jec, null); qs.NotifyJobStoreJobVetoed(trigger, jobDetail, instCode); // Even if trigger got vetoed, we still needs to check to see if it's the trigger's finalized run or not. if (jec.Trigger.GetNextFireTimeUtc() == null) { qs.NotifySchedulerListenersFinalized(jec.Trigger); } Complete(true); } catch (SchedulerException se) { qs.NotifySchedulerListenersError( string.Format(CultureInfo.InvariantCulture, "Error during veto of Job {0}: couldn't finalize execution.", jec.JobDetail.Key), se); } break; } DateTimeOffset startTime = SystemTime.UtcNow(); DateTimeOffset endTime; // Execute the job try { if (log.IsDebugEnabled) { log.Debug("Calling Execute on job " + jobDetail.Key); } job.Execute(jec); endTime = SystemTime.UtcNow(); } catch (JobExecutionException jee) { endTime = SystemTime.UtcNow(); jobExEx = jee; log.Info(string.Format(CultureInfo.InvariantCulture, "Job {0} threw a JobExecutionException: ", jobDetail.Key) + "{0}", jobExEx); } catch (Exception e) { endTime = SystemTime.UtcNow(); log.Error(string.Format(CultureInfo.InvariantCulture, "Job {0} threw an unhandled Exception: ", jobDetail.Key) + "{0}", e); SchedulerException se = new SchedulerException("Job threw an unhandled exception.", e); qs.NotifySchedulerListenersError( string.Format(CultureInfo.InvariantCulture, "Job {0} threw an exception.", jec.JobDetail.Key), se); jobExEx = new JobExecutionException(se, false); } jec.JobRunTime = endTime - startTime; // notify all job listeners if (!NotifyJobListenersComplete(jec, jobExEx)) { break; } instCode = SchedulerInstruction.NoInstruction; // update the trigger try { instCode = trigger.ExecutionComplete(jec, jobExEx); if (log.IsDebugEnabled) { log.Debug(string.Format(CultureInfo.InvariantCulture, "Trigger instruction : {0}", instCode)); } } 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 == SchedulerInstruction.ReExecuteJob) { if (log.IsDebugEnabled) { log.Debug("Rescheduling trigger to reexecute"); } jec.IncrementRefireCount(); try { Complete(false); } catch (SchedulerException se) { qs.NotifySchedulerListenersError( string.Format(CultureInfo.InvariantCulture, "Error executing Job {0}: couldn't finalize execution.", jec.JobDetail.Key), se); } continue; } try { Complete(true); } catch (SchedulerException se) { qs.NotifySchedulerListenersError( string.Format(CultureInfo.InvariantCulture, "Error executing Job {0}: couldn't finalize execution.", jec.JobDetail.Key), se); continue; } qs.NotifyJobStoreJobComplete(trigger, jobDetail, instCode); break; } while (true); } finally { qs.RemoveInternalSchedulerListener(this); if (jec != null && jec.JobInstance != null) { qs.JobFactory.ReturnJob(jec.JobInstance); } } }
public static IJob Delay(this IJob job, TimeSpan delay) => new Job(async(token) => { await Task.Delay(delay, token); await job.Execute(token); });
public Task Execute(IJobExecutionContext context) => _innerJob.Execute(context);
/// <summary> /// Called by the <see cref="T:Quartz.IScheduler" /> when a <see cref="T:Quartz.ITrigger" /> /// fires that is associated with the <see cref="T:Quartz.IJob" />. /// </summary> /// <remarks> /// The implementation may wish to set a result object on the /// JobExecutionContext before this method exits. The result itself /// is meaningless to Quartz, but may be informative to /// <see cref="T:Quartz.IJobListener" />s or /// <see cref="T:Quartz.ITriggerListener" />s that are watching the job's /// execution. /// </remarks> /// <param name="context">The execution context.</param> /// <exception cref="SchedulerConfigException">Job cannot be instantiated.</exception> public void Execute(IJobExecutionContext context) { var childContainer = unityContainer.CreateChildContainer(); try { RunningJob = (IJob)childContainer.Resolve(bundle.JobDetail.JobType); RunningJob.Execute(context); } catch (JobExecutionException) { throw; } catch (Exception ex) { throw new JobExecutionException(string.Format(CultureInfo.InvariantCulture, "Failed to execute Job '{0}' of type '{1}'", bundle.JobDetail.Key, bundle.JobDetail.JobType), ex); } finally { RunningJob = null; childContainer.Dispose(); } }
public Task Execute(IJobExecutionContext context) { return(_job.Execute(context)); }
/// <summary> /// Called by the <see cref="T:Quartz.IScheduler" /> when a <see cref="T:Quartz.ITrigger" /> /// fires that is associated with the <see cref="T:Quartz.IJob" />. /// </summary> /// <remarks> /// The implementation may wish to set a result object on the /// JobExecutionContext before this method exits. The result itself /// is meaningless to Quartz, but may be informative to /// <see cref="T:Quartz.IJobListener" />s or /// <see cref="T:Quartz.ITriggerListener" />s that are watching the job's /// execution. /// </remarks> /// <param name="context">The execution context.</param> /// <exception cref="SchedulerConfigException">Job cannot be instantiated.</exception> public void Execute(IJobExecutionContext context) { var childContainer = _unityContainer.CreateChildContainer(); try { try { RunningJob = (IJob)childContainer.Resolve(Bundle.JobDetail.JobType); } catch (Exception ex) { throw new JobExecutionException(string.Format("Failed to instantiate Job '{0}' of type '{1}'", Bundle.JobDetail.Key, Bundle.JobDetail.JobType), ex); } RunningJob.Execute(context); } catch (JobExecutionException) { throw; } catch (Exception ex) { throw new JobExecutionException( string.Format("Unhandled exception in job '{0}'. {1}", Bundle.JobDetail.Key, ex.Message), ex); } finally { ClearJob(); childContainer.Dispose(); } }
internal bool ExecuteJob(IJob job, out Exception ex) { bool success = false; ex = null; try { // Execute the job, with a timeout if necessary. int timeout = job.Timeout < 0 ? 60000 : job.Timeout; if (timeout > 0) { this.logger.Info("Worker {0} ({1}) is executing job '{2}' with timeout {3}.", this.name, this.id, job.Name, job.Timeout); new Action(job.Execute).InvokeWithTimeout(timeout); } else { this.logger.Info("Worker {0} ({1}) is executing job '{2}' with no timeout.", this.name, this.id, job.Name); job.Execute(); } success = true; } catch (Exception tx) { ex = tx; } return success; }
private void Run(IWindsorContainer container, bool isLeanEngine, bool isReceiveWO) { if (isLeanEngine) { lelog.Info("----------------------------------Invincible's dividing line---------------------------------------"); lelog.Info("BatchJobs run start."); } else if (isReceiveWO) { rwolog.Info("----------------------------------Invincible's dividing line---------------------------------------"); rwolog.Info("BatchJobs run start."); } else { log.Info("----------------------------------Invincible's dividing line---------------------------------------"); log.Info("BatchJobs run start."); } IList <BatchTrigger> tobeFiredTriggerList = this.batchTriggerMgr.GetTobeFiredTrigger(); if (tobeFiredTriggerList != null && tobeFiredTriggerList.Count > 0) { foreach (BatchTrigger tobeFiredTrigger in tobeFiredTriggerList) { bool isSuccess = true; if (isLeanEngine && tobeFiredTrigger.Id != 2 && tobeFiredTrigger.Id != 23 && tobeFiredTrigger.Id != 51 && tobeFiredTrigger.Id != 54 && tobeFiredTrigger.Id != 55 && tobeFiredTrigger.Id != 56 && tobeFiredTrigger.Id != 7) { continue; } if (isReceiveWO && tobeFiredTrigger.Id != 57 && tobeFiredTrigger.Id != 50) { continue; } if (!isLeanEngine && !isReceiveWO && tobeFiredTrigger.Id != 8 && tobeFiredTrigger.Id != 16 && tobeFiredTrigger.Id != 20) { continue; } BatchJobDetail jobDetail = tobeFiredTrigger.BatchJobDetail; BatchRunLog runLog = new BatchRunLog(); try { #region Job运行前处理 if (isLeanEngine) { lelog.Info("Start run job. JobId:" + jobDetail.Id + ", JobName:" + jobDetail.Name); } else if (isReceiveWO) { rwolog.Info("Start run job. JobId:" + jobDetail.Id + ", JobName:" + jobDetail.Name); } else { log.Info("Start run job. JobId:" + jobDetail.Id + ", JobName:" + jobDetail.Name); } runLog.BatchJobDetail = jobDetail; runLog.BatchTrigger = tobeFiredTrigger; runLog.StartTime = DateTime.Now; runLog.Status = "InProcess"; this.batchRunLogMgr.CreateBatchRunLog(runLog); #endregion #region 运行Job JobDataMap dataMap = new JobDataMap(); #region Job参数获取 IList <BatchJobParameter> batchJobParameterList = this.batchJobParameterMgr.GetBatchJobParameter(jobDetail.Id); if (batchJobParameterList != null && batchJobParameterList.Count > 0) { foreach (BatchJobParameter batchJobParameter in batchJobParameterList) { if (isLeanEngine) { lelog.Debug("Set Job Parameter Name:" + batchJobParameter.ParameterName + ", Value:" + batchJobParameter.ParameterValue); } else if (isReceiveWO) { rwolog.Debug("Set Job Parameter Name:" + batchJobParameter.ParameterName + ", Value:" + batchJobParameter.ParameterValue); } else { log.Debug("Set Job Parameter Name:" + batchJobParameter.ParameterName + ", Value:" + batchJobParameter.ParameterValue); } dataMap.PutData(batchJobParameter.ParameterName, batchJobParameter.ParameterValue); } } #endregion #region Trigger参数获取 IList <BatchTriggerParameter> batchTriggerParameterList = this.batchTriggerParameterMgr.GetBatchTriggerParameter(tobeFiredTrigger.Id); if (batchTriggerParameterList != null && batchTriggerParameterList.Count > 0) { foreach (BatchTriggerParameter batchTriggerParameter in batchTriggerParameterList) { if (isLeanEngine) { lelog.Debug("Set Trigger Parameter Name:" + batchTriggerParameter.ParameterName + ", Value:" + batchTriggerParameter.ParameterValue); } else if (isReceiveWO) { rwolog.Debug("Set Trigger Parameter Name:" + batchTriggerParameter.ParameterName + ", Value:" + batchTriggerParameter.ParameterValue); } else { log.Debug("Set Trigger Parameter Name:" + batchTriggerParameter.ParameterName + ", Value:" + batchTriggerParameter.ParameterValue); } dataMap.PutData(batchTriggerParameter.ParameterName, batchTriggerParameter.ParameterValue); } } #endregion #region 初始化JobRunContext JobRunContext jobRunContext = new JobRunContext(tobeFiredTrigger, jobDetail, dataMap, container); #endregion #region 调用Job IJob job = container.Resolve <IJob>(jobDetail.ServiceName); if (isLeanEngine) { lelog.Debug("Start run job: " + jobDetail.ServiceName); } else if (isReceiveWO) { rwolog.Debug("Start run job: " + jobDetail.ServiceName); } else { log.Debug("Start run job: " + jobDetail.ServiceName); } job.Execute(jobRunContext); #endregion #endregion #region Job运行后处理 if (isLeanEngine) { lelog.Info("Job run successful. JobId:" + jobDetail.Id + ", JobName:" + jobDetail.Name); } else if (isReceiveWO) { rwolog.Info("Job run successful. JobId:" + jobDetail.Id + ", JobName:" + jobDetail.Name); } else { log.Info("Job run successful. JobId:" + jobDetail.Id + ", JobName:" + jobDetail.Name); } runLog.EndTime = DateTime.Now; runLog.Status = "Successful"; this.batchRunLogMgr.UpdateBatchRunLog(runLog); #endregion } catch (Exception ex) { try { this.batchTriggerMgr.CleanSession(); isSuccess = false; if (isLeanEngine) { lelog.Error("Job run failure. JobId:" + jobDetail.Id + ", JobName:" + jobDetail.Name, ex); } else if (isReceiveWO) { rwolog.Error("Job run failure. JobId:" + jobDetail.Id + ", JobName:" + jobDetail.Name, ex); } else { log.Error("Job run failure. JobId:" + jobDetail.Id + ", JobName:" + jobDetail.Name, ex); } runLog.EndTime = DateTime.Now; runLog.Status = "Failure"; if (ex.Message != null && ex.Message.Length > 255) { runLog.Message = ex.Message.Substring(0, 255); } else { runLog.Message = ex.Message; } this.batchRunLogMgr.UpdateBatchRunLog(runLog); } catch (Exception ex1) { if (isLeanEngine) { lelog.Error("", ex1); } else if (isReceiveWO) { rwolog.Error("", ex1); } else { log.Error("", ex1); } } } finally { #region 更新BatchTrigger try { BatchTrigger oldTobeFiredTrigger = this.batchTriggerMgr.LoadBatchTrigger(tobeFiredTrigger.Id); oldTobeFiredTrigger.TimesTriggered++; oldTobeFiredTrigger.PreviousFireTime = oldTobeFiredTrigger.NextFireTime; if (oldTobeFiredTrigger.RepeatCount != 0 && oldTobeFiredTrigger.TimesTriggered >= oldTobeFiredTrigger.RepeatCount) { //关闭Trigger if (isLeanEngine) { lelog.Debug("Close Trigger:" + oldTobeFiredTrigger.Name); } else if (isReceiveWO) { rwolog.Debug("Close Trigger:" + oldTobeFiredTrigger.Name); } else { log.Debug("Close Trigger:" + oldTobeFiredTrigger.Name); } oldTobeFiredTrigger.Status = BusinessConstants.CODE_MASTER_STATUS_VALUE_CLOSE; oldTobeFiredTrigger.NextFireTime = null; } else { if (isSuccess) { //设置下次运行时间 if (isLeanEngine) { lelog.Debug("Set Trigger Next Start Time, Add:" + oldTobeFiredTrigger.Interval.ToString() + " " + oldTobeFiredTrigger.IntervalType); } else if (isReceiveWO) { rwolog.Debug("Set Trigger Next Start Time, Add:" + oldTobeFiredTrigger.Interval.ToString() + " " + oldTobeFiredTrigger.IntervalType); } else { log.Debug("Set Trigger Next Start Time, Add:" + oldTobeFiredTrigger.Interval.ToString() + " " + oldTobeFiredTrigger.IntervalType); } DateTime dateTimeNow = DateTime.Now; if (!oldTobeFiredTrigger.NextFireTime.HasValue) { oldTobeFiredTrigger.NextFireTime = dateTimeNow; } while (oldTobeFiredTrigger.NextFireTime.Value <= dateTimeNow) { if (oldTobeFiredTrigger.IntervalType == BusinessConstants.DATETIME_TYPE_YEAR) { oldTobeFiredTrigger.NextFireTime = oldTobeFiredTrigger.NextFireTime.Value.AddYears(oldTobeFiredTrigger.Interval); } else if (oldTobeFiredTrigger.IntervalType == BusinessConstants.DATETIME_TYPE_MONTH) { oldTobeFiredTrigger.NextFireTime = oldTobeFiredTrigger.NextFireTime.Value.AddMonths(oldTobeFiredTrigger.Interval); } else if (oldTobeFiredTrigger.IntervalType == BusinessConstants.DATETIME_TYPE_DAY) { oldTobeFiredTrigger.NextFireTime = oldTobeFiredTrigger.NextFireTime.Value.AddDays(oldTobeFiredTrigger.Interval); } else if (oldTobeFiredTrigger.IntervalType == BusinessConstants.DATETIME_TYPE_HOUR) { oldTobeFiredTrigger.NextFireTime = oldTobeFiredTrigger.NextFireTime.Value.AddHours(oldTobeFiredTrigger.Interval); } else if (oldTobeFiredTrigger.IntervalType == BusinessConstants.DATETIME_TYPE_MINUTE) { oldTobeFiredTrigger.NextFireTime = oldTobeFiredTrigger.NextFireTime.Value.AddMinutes(oldTobeFiredTrigger.Interval); } else if (oldTobeFiredTrigger.IntervalType == BusinessConstants.DATETIME_TYPE_SECOND) { oldTobeFiredTrigger.NextFireTime = oldTobeFiredTrigger.NextFireTime.Value.AddSeconds(oldTobeFiredTrigger.Interval); } else if (oldTobeFiredTrigger.IntervalType == BusinessConstants.DATETIME_TYPE_MILLISECOND) { oldTobeFiredTrigger.NextFireTime = oldTobeFiredTrigger.NextFireTime.Value.AddMilliseconds(oldTobeFiredTrigger.Interval); } else { throw new ArgumentException("invalid Interval Type:" + oldTobeFiredTrigger.IntervalType); } } if (isLeanEngine) { lelog.Debug("Trigger Next Start Time is set as:" + oldTobeFiredTrigger.NextFireTime.Value.ToString("yyyy-MM-dd HH:mm:ss")); } else if (isReceiveWO) { rwolog.Debug("Trigger Next Start Time is set as:" + oldTobeFiredTrigger.NextFireTime.Value.ToString("yyyy-MM-dd HH:mm:ss")); } else { log.Debug("Trigger Next Start Time is set as:" + oldTobeFiredTrigger.NextFireTime.Value.ToString("yyyy-MM-dd HH:mm:ss")); } } } this.batchTriggerMgr.UpdateBatchTrigger(oldTobeFiredTrigger); } catch (Exception ex) { if (isLeanEngine) { lelog.Error("Error occur when update batch trigger.", ex); } else if (isReceiveWO) { rwolog.Error("Error occur when update batch trigger.", ex); } else { log.Error("Error occur when update batch trigger.", ex); } } #endregion } } } else { if (isLeanEngine) { lelog.Info("No job found may run in this batch."); } else if (isReceiveWO) { rwolog.Info("No job found may run in this batch."); } else { log.Info("No job found may run in this batch."); } } if (isLeanEngine) { lelog.Info("BatchJobs run end."); } else if (isReceiveWO) { rwolog.Info("BatchJobs run end."); } else { log.Info("BatchJobs run end."); } }
/// <summary> /// Called by the <see cref="T:Quartz.IScheduler" /> when a <see cref="T:Quartz.ITrigger" /> /// fires that is associated with the <see cref="T:Quartz.IJob" />. /// </summary> /// <remarks> /// The implementation may wish to set a result object on the /// JobExecutionContext before this method exits. The result itself /// is meaningless to Quartz, but may be informative to /// <see cref="T:Quartz.IJobListener" />s or /// <see cref="T:Quartz.ITriggerListener" />s that are watching the job's /// execution. /// </remarks> /// <param name="context">The execution context.</param> /// <exception cref="SchedulerConfigException">Job cannot be instantiated.</exception> public void Execute(IJobExecutionContext context) { var scope = _lifetimeScope.BeginLifetimeScope(_scopeName); try { RunningJob = CreateJob(scope); RunningJob.Execute(context); } catch (Exception ex) { throw new SchedulerConfigException(string.Format(CultureInfo.InvariantCulture, "Failed to instantiate Job '{0}' of type '{1}'", _bundle.JobDetail.Key, _bundle.JobDetail.JobType), ex); } finally { RunningJob = null; scope.Dispose(); } }
public void Execute(IJobExecutionContext context) { Console.WriteLine("See, i am decorating the Job: " + typeof(JobWithInjectedDependenciesDecorated).Name + " with a logger!"); _decoratee.Execute(context); }
protected override void Execute() => _job.Execute();
private void RunJob(IJob job) { try { DateTime start = DateTime.Now; var newJobs = job.Execute(); DateTime end = DateTime.Now; logger.Info("{0} finished in {2} s. and returned {1} new jobs.", job.Name, newJobs.Count, (end-start).TotalSeconds); foreach (var newJob in newJobs) { AddJob(newJob); } } catch (Exception exp2) { logger.Error(exp2, "{0} failed while executing.", job.Name); } }
private void UpdateUI(IJob job) { job.Execute(this); }
/// <summary> /// Action creation helper. /// Given a job, job parameters and a job execution, /// will wrap the execution of the job into a <see cref="System.Action"/>. /// </summary> /// <param name="job">the job to execute</param> /// <param name="jobParameters">the job parameters</param> /// <param name="jobExecution">the job execution</param> /// <returns></returns> private static Action CreateJobAction(IJob job, JobParameters jobParameters, JobExecution jobExecution) { Action jobAction = (() => { try { Logger.Info("Job: [{0} ] launched with the following parameters:[{1}]",job,jobParameters); job.Execute(jobExecution); Logger.Info("Job: [{0}] completed with the following parameters:[{1}] and the following status: [{2}]", job,jobParameters,jobExecution.Status); } catch (Exception exception) { Logger.Info("Job: [{0}] failed unexpectedly and fatally with the following parameters: [{1}]",job,exception); throw; } }); return jobAction; }
private void RunJobCore(IJobContext context, Operation operation, IJob job) { // Run the job. If the job fails, ignore that exception as well but log it too! try { job.Execute(context, operation); } catch (Exception ex) { string message = (job.IsAsync) ? Properties.Resources.JobExecuteAsyncFailed : Properties.Resources.JobExecuteSyncFailed; // Be careful when processing the jobs, we don't want a malicious job to terminate the process! Logger.Instance.LogFormat(LogType.Warning, this, string.Format(message, job.GetType().Name)); Logger.Instance.LogException(this, ex); } }
/// <summary> /// This method has to be implemented in order that starting of the thread causes the object's /// run method to be called in that separately executing thread. /// </summary> /// <param name="cancellationToken">The cancellation instruction.</param> public virtual async Task Run(CancellationToken cancellationToken = default) { qs !.AddInternalSchedulerListener(this); try { IOperableTrigger trigger = (IOperableTrigger)jec !.Trigger; IJobDetail jobDetail = jec.JobDetail; do { JobExecutionException?jobExEx = null; IJob job = jec.JobInstance; try { Begin(); } catch (SchedulerException se) { string msg = $"Error executing Job {jec.JobDetail.Key}: couldn't begin execution."; await qs.NotifySchedulerListenersError(msg, se, cancellationToken).ConfigureAwait(false); break; } // notify job & trigger listeners... SchedulerInstruction instCode; try { if (!await NotifyListenersBeginning(jec, cancellationToken).ConfigureAwait(false)) { break; } } catch (VetoedException) { try { instCode = trigger.ExecutionComplete(jec, null); await qs.NotifyJobStoreJobVetoed(trigger, jobDetail, instCode, cancellationToken).ConfigureAwait(false); // Even if trigger got vetoed, we still needs to check to see if it's the trigger's finalized run or not. if (jec.Trigger.GetNextFireTimeUtc() == null) { await qs.NotifySchedulerListenersFinalized(jec.Trigger, cancellationToken).ConfigureAwait(false); } Complete(true); } catch (SchedulerException se) { string msg = $"Error during veto of Job {jec.JobDetail.Key}: couldn't finalize execution."; await qs.NotifySchedulerListenersError(msg, se, cancellationToken).ConfigureAwait(false); } break; } DateTimeOffset startTime = SystemTime.UtcNow(); DateTimeOffset endTime; // Execute the job try { if (log.IsDebugEnabled()) { log.Debug("Calling Execute on job " + jobDetail.Key); } await job.Execute(jec).ConfigureAwait(false); endTime = SystemTime.UtcNow(); } catch (OperationCanceledException) { endTime = SystemTime.UtcNow(); log.InfoFormat($"Job {jobDetail.Key} was cancelled"); } catch (JobExecutionException jee) { endTime = SystemTime.UtcNow(); jobExEx = jee; log.ErrorException($"Job {jobDetail.Key} threw a JobExecutionException: ", jobExEx); } catch (Exception e) { endTime = SystemTime.UtcNow(); log.ErrorException($"Job {jobDetail.Key} threw an unhandled Exception: ", e); SchedulerException se = new SchedulerException("Job threw an unhandled exception.", e); string msg = $"Job {jec.JobDetail.Key} threw an exception."; await qs.NotifySchedulerListenersError(msg, se, cancellationToken).ConfigureAwait(false); jobExEx = new JobExecutionException(se, false); } jec.JobRunTime = endTime - startTime; // notify all job listeners if (!await NotifyJobListenersComplete(jec, jobExEx, cancellationToken).ConfigureAwait(false)) { break; } instCode = SchedulerInstruction.NoInstruction; // update the trigger try { instCode = trigger.ExecutionComplete(jec, jobExEx); if (log.IsDebugEnabled()) { log.Debug($"Trigger instruction : {instCode}"); } } catch (Exception e) { // If this happens, there's a bug in the trigger... SchedulerException se = new SchedulerException("Trigger threw an unhandled exception.", e); await qs.NotifySchedulerListenersError("Please report this error to the Quartz developers.", se, cancellationToken).ConfigureAwait(false); } // notify all trigger listeners if (!await NotifyTriggerListenersComplete(jec, instCode, cancellationToken).ConfigureAwait(false)) { break; } // update job/trigger or re-Execute job if (instCode == SchedulerInstruction.ReExecuteJob) { if (log.IsDebugEnabled()) { log.Debug("Rescheduling trigger to reexecute"); } jec.IncrementRefireCount(); try { Complete(false); } catch (SchedulerException se) { await qs.NotifySchedulerListenersError($"Error executing Job {jec.JobDetail.Key}: couldn't finalize execution.", se, cancellationToken).ConfigureAwait(false); } continue; } try { Complete(true); } catch (SchedulerException se) { await qs.NotifySchedulerListenersError($"Error executing Job {jec.JobDetail.Key}: couldn't finalize execution.", se, cancellationToken).ConfigureAwait(false); continue; } await qs.NotifyJobStoreJobComplete(trigger, jobDetail, instCode, cancellationToken).ConfigureAwait(false); break; } while (true); } finally { qs.RemoveInternalSchedulerListener(this); if (jec != null) { if (jec.JobInstance != null) { qs.JobFactory.ReturnJob(jec.JobInstance); } jec.Dispose(); } } }
public async Task Execute(IJobExecutionContext context) { await actualJob.Execute(context); scope.Dispose(); }
private void RunJobCore(IJobContext context, Operation operation, IJob job) { try { job.Execute(context, operation); Logger.Instance.LogFormat(LogType.Trace, this, Resources.JobExecuteFinished, job.GetType().Name); } catch (Exception ex) { string message = (job.IsAsync) ? Properties.Resources.JobExecuteAsyncFailed : Properties.Resources.JobExecuteSyncFailed; Logger.Instance.LogFormat(LogType.Warning, this, string.Format(message, job.GetType().Name)); Logger.Instance.LogException(this, ex); } }
/// <summary> /// Executes the job specified in the job context and updates the jobstore accordingly. /// </summary> /// <param name="jobContext">The job context.</param> public void ExecuteJob(JobContext jobContext) { if (jobContext == null) { throw new ArgumentNullException("jobContext"); } if (jobContext.JobInstance == null) { throw new ArgumentNullException("jobContext.JobInstance"); } if (jobContext.JobData == null) { throw new ArgumentNullException("jobContext.JobData"); } if (jobContext.JobManager == null) { throw new ArgumentNullException("jobContext.JobManager"); } if (!(jobContext.JobInstance is IJob)) { throw new ArgumentException("BackgroundJobExecutor : jobContext.JobInstance must be of type IJob"); } IJob backgroundJob = (IJob)jobContext.JobInstance; IJobManager jobManager = jobContext.JobManager; JobData jobData = jobContext.JobData; ILoggingProvider logger = jobContext.JobManager.Logger; Debug.WriteLine(DateTime.Now.ToString("dd/mm/yyyy HH:mm:ss:fffffff") + " : " + jobContext.JobData.Id + " start execution."); try { jobData.LastStartTime = DateTime.Now; jobData.LastEndTime = null; jobData.LastErrorMessage = null; jobData.Status = JobStatus.Executing; jobManager.JobStore.UpdateJob(jobData); JobExecutionResult returnValue = backgroundJob.Execute(jobContext.JobData.Data, jobContext.JobData.MetaData); if (returnValue == null) { throw new ArgumentException("Execute(string jobData, string recoveryData) for job '" + jobContext.JobData.Id + "' returned null."); } jobData.LastEndTime = DateTime.Now; switch (returnValue.ResultStatus) { case JobResultStatus.Success: jobData.Status = JobStatus.Done; break; case JobResultStatus.FailAutoRetry: jobData.Status = JobStatus.FailAutoRetry; break; case JobResultStatus.FailRetry: jobData.Status = JobStatus.FailRetry; break; default: jobData.Status = JobStatus.Fail; break; } jobData.LastErrorMessage = (!string.IsNullOrEmpty(returnValue.ErrorMessage) ? returnValue.ErrorMessage : null); if (returnValue.MetaData != null && jobData.MetaData != returnValue.MetaData) { jobData.MetaData = returnValue.MetaData; } jobManager.JobStore.UpdateJob(jobData); } catch (ThreadAbortException) { throw; } catch (Exception ex) { string message = Helpers.Utils.GetExceptionMessage(ex); jobData.Status = JobStatus.Fail; jobData.LastErrorMessage = message; jobData.LastEndTime = DateTime.Now; jobManager.JobStore.UpdateJob(jobData); } try { if (!jobData.SuppressHistory && jobData.Status != JobStatus.Ready) //Status check added for the extreme case where the thread was aborted { jobManager.JobStore.CreateJobExecutionHistory(jobData); } } catch (Exception ex) { logger.LogException("Could not create job execution history record.", ex); } Debug.WriteLine(DateTime.Now.ToString("dd/mm/yyyy HH:mm:ss:fffffff") + " : " + jobContext.JobData.Id + " end execution."); if (jobData.DeleteWhenDone && jobData.Status == JobStatus.Done) { try { jobManager.JobStore.DeleteJob(jobData); return; } catch (Exception ex) { logger.LogException("Could not delete job that was set to 'DeleteWhenDone'.", ex); } } if (jobData.Status == JobStatus.FailAutoRetry) { try { jobManager.JobStore.SetJobStatus(jobData.Id, jobData.Status, JobStatus.Ready); } catch (Exception ex) { logger.LogException("Could not set job to ready after FailAutoRetry result.", ex); } } if (jobData.Schedule != null) { try { jobManager.JobStore.SetJobStatus(jobData.Id, jobData.Status, JobStatus.Ready); } catch (Exception ex) { logger.LogException("Could not set job to ready for next scheduled execution.", ex); } } }