private void DoRescheduleJob(IScheduler sched, IMutableTrigger trigger, ITrigger oldTrigger) { // if this is a trigger with default start time we can consider relative scheduling if (oldTrigger != null && trigger.StartTimeUtc - SystemTime.UtcNow() < TimeSpan.FromSeconds(5) && ScheduleTriggerRelativeToReplacedTrigger) { Log.Debug("Using relative scheduling for trigger with key {0}", trigger.Key); var oldTriggerPreviousFireTime = oldTrigger.GetPreviousFireTimeUtc(); trigger.StartTimeUtc = oldTrigger.StartTimeUtc; ((IOperableTrigger)trigger).SetPreviousFireTimeUtc(oldTriggerPreviousFireTime); ((IOperableTrigger)trigger).SetNextFireTimeUtc(trigger.GetFireTimeAfter(oldTriggerPreviousFireTime)); } sched.RescheduleJob(trigger.Key, trigger); }
private void StartQuartz() { IScheduler sched = new StdSchedulerFactory().GetScheduler(); //==============BossReportJob 开始================ JobDetailImpl jdBossReport = new JobDetailImpl("jdBossReportJob", typeof(BossReportJob)); IMutableTrigger triggerBossReport = CronScheduleBuilder.DailyAtHourAndMinute(23, 45).Build();//每天23:45执行一次 triggerBossReport.Key = new TriggerKey("triggerBossReportJob"); sched.ScheduleJob(jdBossReport, triggerBossReport); //==============BossReportJob 结束================ sched.Start(); }
private void StartQuartz() { IScheduler sched = new StdSchedulerFactory().GetScheduler(); JobDetailImpl jobAutoConfirm = new JobDetailImpl("jobAutoConfirm", typeof(AutoConfirmJob)); CalendarIntervalScheduleBuilder builder = CalendarIntervalScheduleBuilder.Create(); builder.WithInterval(2, IntervalUnit.Minute); IMutableTrigger triggerAutoConfirm = builder.Build(); triggerAutoConfirm.Key = new TriggerKey("triggerAutoConfirm"); sched.ScheduleJob(jobAutoConfirm, triggerAutoConfirm); sched.Start(); }
//如果是网站项目,将这个执行方法放到Global里面 private static void startQuartz() { IScheduler sched = new StdSchedulerFactory().GetScheduler(); //给老板的报表开始 JobDetailImpl jdBossReport = new JobDetailImpl("jdBossReport", typeof(BossReportJob)); IMutableTrigger triggerBossReport = CronScheduleBuilder.DailyAtHourAndMinute(14, 11).Build();//每天23:45执行一次 triggerBossReport.Key = new TriggerKey("triggerBossReport"); sched.ScheduleJob(jdBossReport, triggerBossReport); //给老板的报表结束 sched.Start(); }
//Quartz 使用 static void Quartz() { //如果出了异常 不会报错 所以用TryCatch IScheduler sched = new StdSchedulerFactory().GetScheduler(); JobDetailImpl jdBossReport = new JobDetailImpl("jdTest", typeof(TestJob)); //IMutableTrigger triggerBossReport = CronScheduleBuilder.DailyAtHourAndMinute(19, 38).Build();//每天23.45 var bulider = CalendarIntervalScheduleBuilder.Create(); bulider.WithInterval(3, IntervalUnit.Second); IMutableTrigger triggerBossReport = bulider.Build(); triggerBossReport.Key = new TriggerKey("triggerTest"); sched.ScheduleJob(jdBossReport, triggerBossReport); sched.Start(); Console.WriteLine("ok");; Console.ReadKey(); }
private static bool ValidateMisfireInstruction(IMutableTrigger qTrigger, int?misfireInstruction, int nvlValue, object id) { if (qTrigger == null) { return(false); } try { qTrigger.MisfireInstruction = misfireInstruction ?? nvlValue; return(true); } catch (Exception ex) { Log.Error(string.Format("The misfire instruction code '{0}' is invalid for this type of trigger '{1}' (id: '{2}').", misfireInstruction, qTrigger.GetType(), id), ex); return(false); } }
void Application_Start(object sender, EventArgs e) { // 在应用程序启动时运行的代码 RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); IScheduler sched = new StdSchedulerFactory().GetScheduler(); JobDetailImpl jdBossReport = new JobDetailImpl("jdTest", typeof(TestJob)); CalendarIntervalScheduleBuilder builder = CalendarIntervalScheduleBuilder.Create(); builder.WithInterval(5, IntervalUnit.Second); IMutableTrigger triggerBossReport = builder.Build(); triggerBossReport.Key = new TriggerKey("triggerTest"); sched.ScheduleJob(jdBossReport, triggerBossReport); sched.Start(); }
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); IScheduler sched = new StdSchedulerFactory().GetScheduler(); //创建一个工作对象 JobDetailImpl jdBossReport = new JobDetailImpl("jdTest", typeof(TestJob)); int day = int.Parse(ConfigurationManager.AppSettings["day"]); int huor = int.Parse(ConfigurationManager.AppSettings["hour"]); int mi = int.Parse(ConfigurationManager.AppSettings["mi"]); //创建触发条件 IMutableTrigger triggerBossReport = CronScheduleBuilder.MonthlyOnDayAndHourAndMinute(day, huor, mi).Build(); //设置触发条件的键名 triggerBossReport.Key = new TriggerKey("test"); //给计划按触发条件执行工作 sched.ScheduleJob(jdBossReport, triggerBossReport); //计划启动 sched.Start(); // BundleConfig.RegisterBundles(BundleTable.Bundles); ContainerBuilder cb = new ContainerBuilder(); //把当前程序集中的 Controller 都注册 cb.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired(); //注册实现IUserBLL的实现类 // cb.RegisterType<UserBLL>().As<IUserBLL>(); Assembly ass = Assembly.Load("BLL"); cb.RegisterAssemblyTypes(ass).AsImplementedInterfaces().PropertiesAutowired().SingleInstance(); IContainer ioc = cb.Build(); //注册系统级别的 DependencyResolver,这样当 MVC 框架创建 Controller 等对象的时候都是管 Autofac 要对象。 DependencyResolver.SetResolver(new AutofacDependencyResolver(ioc)); }
public static void ExecuteWithInterval(int second, Action action) { //scheduler IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler(); //more job { //job JobDetailImpl job = new JobDetailImpl("zszTimer", typeof(IntervalJob)); job.JobDataMap.Add("dosth", action); //任务数据 //trigger IMutableTrigger trigger = CalendarIntervalScheduleBuilder.Create() .WithIntervalInSeconds(second).Build(); trigger.Key = new TriggerKey("zszTrigger"); //watch scheduler.ScheduleJob(job, trigger); } //start scheduler.Start(); }
public static void StartSchedul(IHouseUsage2Service houseUsage2, IHouseUsageService houseUsage, ITotalTumoverService totalTumover, ITumoverService tumover, IRegionService region) { houseUsage2Service = houseUsage2; houseUsageService = houseUsage; totalTumoverService = totalTumover; tumoverService = tumover; regionService = region; IScheduler sched = new StdSchedulerFactory().GetScheduler(); JobDetailImpl jdBossReport = new JobDetailImpl("getTumoverJob", typeof(GetTumoverJob)); CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.CronSchedule("0 30 * * * ? *"); //CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.CronSchedule("* * * * * ? *"); IMutableTrigger triggerBossReport = cronScheduleBuilder.Build(); triggerBossReport.Key = new TriggerKey("getTumoverTrigger"); sched.ScheduleJob(jdBossReport, triggerBossReport); sched.Start(); }
protected virtual void ProcessInternal(string xml) { PrepForProcessing(); ValidateXml(xml); MaybeThrowValidationException(); // deserialize as object model XmlSerializer xs = new XmlSerializer(typeof(QuartzXmlConfiguration20)); QuartzXmlConfiguration20 data = (QuartzXmlConfiguration20)xs.Deserialize(new StringReader(xml)); if (data == null) { throw new SchedulerConfigException("Job definition data from XML was null after deserialization"); } // // Extract pre-processing commands // if (data.preprocessingcommands != null) { foreach (preprocessingcommandsType command in data.preprocessingcommands) { if (command.deletejobsingroup != null) { foreach (string s in command.deletejobsingroup) { string deleteJobGroup = s.NullSafeTrim(); if (!String.IsNullOrEmpty(deleteJobGroup)) { jobGroupsToDelete.Add(deleteJobGroup); } } } if (command.deletetriggersingroup != null) { foreach (string s in command.deletetriggersingroup) { string deleteTriggerGroup = s.NullSafeTrim(); if (!String.IsNullOrEmpty(deleteTriggerGroup)) { triggerGroupsToDelete.Add(deleteTriggerGroup); } } } if (command.deletejob != null) { foreach (preprocessingcommandsTypeDeletejob s in command.deletejob) { string name = s.name.TrimEmptyToNull(); string group = s.group.TrimEmptyToNull(); if (name == null) { throw new SchedulerConfigException("Encountered a 'delete-job' command without a name specified."); } jobsToDelete.Add(new JobKey(name, group)); } } if (command.deletetrigger != null) { foreach (preprocessingcommandsTypeDeletetrigger s in command.deletetrigger) { string name = s.name.TrimEmptyToNull(); string group = s.group.TrimEmptyToNull(); if (name == null) { throw new SchedulerConfigException("Encountered a 'delete-trigger' command without a name specified."); } triggersToDelete.Add(new TriggerKey(name, group)); } } } } if (log.IsDebugEnabled) { log.Debug("Found " + jobGroupsToDelete.Count + " delete job group commands."); log.Debug("Found " + triggerGroupsToDelete.Count + " delete trigger group commands."); log.Debug("Found " + jobsToDelete.Count + " delete job commands."); log.Debug("Found " + triggersToDelete.Count + " delete trigger commands."); } // // Extract directives // if (data.processingdirectives != null && data.processingdirectives.Length > 0) { bool overWrite = data.processingdirectives[0].overwriteexistingdata; log.Debug("Directive 'overwrite-existing-data' specified as: " + overWrite); OverWriteExistingData = overWrite; } else { log.Debug("Directive 'overwrite-existing-data' not specified, defaulting to " + OverWriteExistingData); } if (data.processingdirectives != null && data.processingdirectives.Length > 0) { bool ignoreduplicates = data.processingdirectives[0].ignoreduplicates; log.Debug("Directive 'ignore-duplicates' specified as: " + ignoreduplicates); IgnoreDuplicates = ignoreduplicates; } else { log.Debug("Directive 'ignore-duplicates' not specified, defaulting to " + IgnoreDuplicates); } if (data.processingdirectives != null && data.processingdirectives.Length > 0) { bool scheduleRelative = data.processingdirectives[0].scheduletriggerrelativetoreplacedtrigger; log.Debug("Directive 'schedule-trigger-relative-to-replaced-trigger' specified as: " + scheduleRelative); ScheduleTriggerRelativeToReplacedTrigger = scheduleRelative; } else { log.Debug("Directive 'schedule-trigger-relative-to-replaced-trigger' not specified, defaulting to " + ScheduleTriggerRelativeToReplacedTrigger); } // // Extract Job definitions... // List <jobdetailType> jobNodes = new List <jobdetailType>(); if (data.schedule != null) { foreach (var schedule in data.schedule) { if (schedule != null) { if (schedule.job != null) { jobNodes.AddRange(schedule.job); } } } } log.Debug("Found " + jobNodes.Count + " job definitions."); foreach (jobdetailType jobDetailType in jobNodes) { string jobName = jobDetailType.name.TrimEmptyToNull(); string jobGroup = jobDetailType.group.TrimEmptyToNull(); string jobDescription = jobDetailType.description.TrimEmptyToNull(); string jobTypeName = jobDetailType.jobtype.TrimEmptyToNull(); bool jobDurability = jobDetailType.durable; bool jobRecoveryRequested = jobDetailType.recover; Type jobType = typeLoadHelper.LoadType(jobTypeName); IJobDetail jobDetail = JobBuilder.Create(jobType) .WithIdentity(jobName, jobGroup) .WithDescription(jobDescription) .StoreDurably(jobDurability) .RequestRecovery(jobRecoveryRequested) .Build(); if (jobDetailType.jobdatamap != null && jobDetailType.jobdatamap.entry != null) { foreach (entryType entry in jobDetailType.jobdatamap.entry) { string key = entry.key.TrimEmptyToNull(); string value = entry.value.TrimEmptyToNull(); jobDetail.JobDataMap.Add(key, value); } } if (log.IsDebugEnabled) { log.Debug("Parsed job definition: " + jobDetail); } AddJobToSchedule(jobDetail); } // // Extract Trigger definitions... // List <triggerType> triggerEntries = new List <triggerType>(); if (data.schedule != null) { foreach (var schedule in data.schedule) { if (schedule != null && schedule.trigger != null) { triggerEntries.AddRange(schedule.trigger); } } } log.Debug("Found " + triggerEntries.Count + " trigger definitions."); foreach (triggerType triggerNode in triggerEntries) { string triggerName = triggerNode.Item.name.TrimEmptyToNull(); string triggerGroup = triggerNode.Item.group.TrimEmptyToNull(); string triggerDescription = triggerNode.Item.description.TrimEmptyToNull(); string triggerCalendarRef = triggerNode.Item.calendarname.TrimEmptyToNull(); string triggerJobName = triggerNode.Item.jobname.TrimEmptyToNull(); string triggerJobGroup = triggerNode.Item.jobgroup.TrimEmptyToNull(); int triggerPriority = TriggerConstants.DefaultPriority; if (!triggerNode.Item.priority.IsNullOrWhiteSpace()) { triggerPriority = Convert.ToInt32(triggerNode.Item.priority); } DateTimeOffset triggerStartTime = SystemTime.UtcNow(); if (triggerNode.Item.Item != null) { if (triggerNode.Item.Item is DateTime) { triggerStartTime = new DateTimeOffset((DateTime)triggerNode.Item.Item); } else { triggerStartTime = triggerStartTime.AddSeconds(Convert.ToInt32(triggerNode.Item.Item)); } } DateTime?triggerEndTime = triggerNode.Item.endtimeSpecified ? triggerNode.Item.endtime : (DateTime?)null; IScheduleBuilder sched; if (triggerNode.Item is simpleTriggerType) { simpleTriggerType simpleTrigger = (simpleTriggerType)triggerNode.Item; string repeatCountString = simpleTrigger.repeatcount.TrimEmptyToNull(); string repeatIntervalString = simpleTrigger.repeatinterval.TrimEmptyToNull(); int repeatCount = ParseSimpleTriggerRepeatCount(repeatCountString); TimeSpan repeatInterval = repeatIntervalString == null ? TimeSpan.Zero : TimeSpan.FromMilliseconds(Convert.ToInt64(repeatIntervalString)); sched = SimpleScheduleBuilder.Create() .WithInterval(repeatInterval) .WithRepeatCount(repeatCount); if (!simpleTrigger.misfireinstruction.IsNullOrWhiteSpace()) { ((SimpleScheduleBuilder)sched).WithMisfireHandlingInstruction(ReadMisfireInstructionFromString(simpleTrigger.misfireinstruction)); } } else if (triggerNode.Item is cronTriggerType) { cronTriggerType cronTrigger = (cronTriggerType)triggerNode.Item; string cronExpression = cronTrigger.cronexpression.TrimEmptyToNull(); string timezoneString = cronTrigger.timezone.TrimEmptyToNull(); TimeZoneInfo tz = timezoneString != null?TimeZoneInfo.FindSystemTimeZoneById(timezoneString) : null; sched = CronScheduleBuilder.CronSchedule(cronExpression) .InTimeZone(tz); if (!cronTrigger.misfireinstruction.IsNullOrWhiteSpace()) { ((CronScheduleBuilder)sched).WithMisfireHandlingInstruction(ReadMisfireInstructionFromString(cronTrigger.misfireinstruction)); } } else if (triggerNode.Item is calendarIntervalTriggerType) { calendarIntervalTriggerType calendarIntervalTrigger = (calendarIntervalTriggerType)triggerNode.Item; string repeatIntervalString = calendarIntervalTrigger.repeatinterval.TrimEmptyToNull(); IntervalUnit intervalUnit = ParseDateIntervalTriggerIntervalUnit(calendarIntervalTrigger.repeatintervalunit.TrimEmptyToNull()); int repeatInterval = repeatIntervalString == null ? 0 : Convert.ToInt32(repeatIntervalString); sched = CalendarIntervalScheduleBuilder.Create() .WithInterval(repeatInterval, intervalUnit); if (!calendarIntervalTrigger.misfireinstruction.IsNullOrWhiteSpace()) { ((CalendarIntervalScheduleBuilder)sched).WithMisfireHandlingInstruction(ReadMisfireInstructionFromString(calendarIntervalTrigger.misfireinstruction)); } } else { throw new SchedulerConfigException("Unknown trigger type in XML configuration"); } IMutableTrigger trigger = (IMutableTrigger)TriggerBuilder.Create() .WithIdentity(triggerName, triggerGroup) .WithDescription(triggerDescription) .ForJob(triggerJobName, triggerJobGroup) .StartAt(triggerStartTime) .EndAt(triggerEndTime) .WithPriority(triggerPriority) .ModifiedByCalendar(triggerCalendarRef) .WithSchedule(sched) .Build(); if (triggerNode.Item.jobdatamap != null && triggerNode.Item.jobdatamap.entry != null) { foreach (entryType entry in triggerNode.Item.jobdatamap.entry) { string key = entry.key.TrimEmptyToNull(); string value = entry.value.TrimEmptyToNull(); trigger.JobDataMap.Add(key, value); } } if (log.IsDebugEnabled) { log.Debug("Parsed trigger definition: " + trigger); } AddTriggerToSchedule(trigger); } }
private static bool ValidateMisfireInstruction(IMutableTrigger qTrigger, int? misfireInstruction, int nvlValue, object id) { if (qTrigger == null) return false; try { qTrigger.MisfireInstruction = misfireInstruction ?? nvlValue; return true; } catch (Exception ex) { Log.Error(string.Format("The misfire instruction code '{0}' is invalid for this type of trigger '{1}' (id: '{2}').", misfireInstruction, qTrigger.GetType(), id), ex); return false; } }
/// <summary> /// Creates a new builder for the given <see cref="ITrigger" />. /// </summary> /// <param name="trigger">The <see cref="IMutableTrigger" /> to configure.</param> public TriggerBuilder(IMutableTrigger trigger) => Builder = ((Trigger)trigger).Builder;
private void ReportDuplicateTrigger(IMutableTrigger trigger) { Log.WarnFormat("Possibly duplicately named ({0}) trigger in configuration, this can be caused by not having a fixed job key for targeted jobs", trigger.Key); }
protected virtual void AddTriggerToSchedule(IMutableTrigger trigger) { loadedTriggers.Add(trigger); }
/// <summary> /// Schedules the given sets of jobs and triggers. /// </summary> /// <param name="sched">The sched.</param> public virtual void ScheduleJobs(IScheduler sched) { List <IJobDetail> jobs = new List <IJobDetail>(LoadedJobs); List <ITrigger> triggers = new List <ITrigger>(LoadedTriggers); log.Info("Adding " + jobs.Count + " jobs, " + triggers.Count + " triggers."); IDictionary <JobKey, List <IMutableTrigger> > triggersByFQJobName = BuildTriggersByFQJobNameMap(triggers); // add each job, and it's associated triggers while (jobs.Count > 0) { // remove jobs as we handle them... IJobDetail detail = jobs[0]; jobs.Remove(detail); IJobDetail dupeJ = sched.GetJobDetail(detail.Key); if ((dupeJ != null)) { if (!OverWriteExistingData && IgnoreDuplicates) { log.Info("Not overwriting existing job: " + dupeJ.Key); continue; // just ignore the entry } if (!OverWriteExistingData && !IgnoreDuplicates) { throw new ObjectAlreadyExistsException(detail); } } if (dupeJ != null) { log.Info("Replacing job: " + detail.Key); } else { log.Info("Adding job: " + detail.Key); } List <IMutableTrigger> triggersOfJob; triggersByFQJobName.TryGetValue(detail.Key, out triggersOfJob); if (!detail.Durable && (triggersOfJob == null || triggersOfJob.Count == 0)) { if (dupeJ == null) { throw new SchedulerException( "A new job defined without any triggers must be durable: " + detail.Key); } if ((dupeJ.Durable && (sched.GetTriggersOfJob(detail.Key).Count == 0))) { throw new SchedulerException( "Can't change existing durable job without triggers to non-durable: " + detail.Key); } } if (dupeJ != null || detail.Durable) { sched.AddJob(detail, true); // add the job if a replacement or durable } else { bool addJobWithFirstSchedule = true; // Add triggers related to the job... while (triggersOfJob.Count > 0) { IMutableTrigger trigger = triggersOfJob[0]; // remove triggers as we handle them... triggersOfJob.Remove(trigger); bool addedTrigger = false; while (addedTrigger == false) { ITrigger dupeT = sched.GetTrigger(trigger.Key); if (dupeT != null) { if (OverWriteExistingData) { if (log.IsDebugEnabled) { log.Debug( "Rescheduling job: " + trigger.JobKey + " with updated trigger: " + trigger.Key); } } else if (IgnoreDuplicates) { log.Info("Not overwriting existing trigger: " + dupeT.Key); continue; // just ignore the trigger (and possibly job) } else { throw new ObjectAlreadyExistsException(trigger); } if (!dupeT.JobKey.Equals(trigger.JobKey)) { log.WarnFormat("Possibly duplicately named ({0}) triggers in jobs xml file! ", trigger.Key); } sched.RescheduleJob(trigger.Key, trigger); } else { if (log.IsDebugEnabled) { log.Debug( "Scheduling job: " + trigger.JobKey + " with trigger: " + trigger.Key); } try { if (addJobWithFirstSchedule) { sched.ScheduleJob(detail, trigger); // add the job if it's not in yet... addJobWithFirstSchedule = false; } else { sched.ScheduleJob(trigger); } } catch (ObjectAlreadyExistsException) { if (log.IsDebugEnabled) { log.Debug("Adding trigger: " + trigger.Key + " for job: " + detail.Key + " failed because the trigger already existed. " + "This is likely due to a race condition between multiple instances " + "in the cluster. Will try to reschedule instead."); } continue; } } addedTrigger = true; } } } } // add triggers that weren't associated with a new job... (those we already handled were removed above) foreach (IMutableTrigger trigger in triggers) { bool addedTrigger = false; while (!addedTrigger) { ITrigger dupeT = sched.GetTrigger(trigger.Key); if (dupeT != null) { if (OverWriteExistingData) { if (log.IsDebugEnabled) { log.DebugFormat("Rescheduling job: " + trigger.JobKey + " with updated trigger: " + trigger.Key); } } else if (IgnoreDuplicates) { log.Info("Not overwriting existing trigger: " + dupeT.Key); continue; // just ignore the trigger } else { throw new ObjectAlreadyExistsException(trigger); } if (!dupeT.JobKey.Equals(trigger.JobKey)) { log.WarnFormat("Possibly duplicately named ({0}) triggers in jobs xml file! ", trigger.Key); } sched.RescheduleJob(trigger.Key, trigger); } else { if (log.IsDebugEnabled) { log.Debug("Scheduling job: " + trigger.JobKey + " with trigger: " + trigger.Key); } try { sched.ScheduleJob(trigger); } catch (ObjectAlreadyExistsException) { if (log.IsDebugEnabled) { log.Debug( "Adding trigger: " + trigger.Key + " for job: " + trigger.JobKey + " failed because the trigger already existed. " + "This is likely due to a race condition between multiple instances " + "in the cluster. Will try to reschedule instead."); } continue; } } addedTrigger = true; } } }
/// <summary> /// Schedules the given sets of jobs and triggers. /// </summary> /// <param name="sched">The sched.</param> public virtual void ScheduleJobs(IScheduler sched) { List <IJobDetail> jobs = new List <IJobDetail>(LoadedJobs); List <ITrigger> triggers = new List <ITrigger>(LoadedTriggers); log.Info("Adding " + jobs.Count + " jobs, " + triggers.Count + " triggers."); IDictionary <JobKey, List <IMutableTrigger> > triggersByFQJobName = BuildTriggersByFQJobNameMap(triggers); // add each job, and it's associated triggers while (jobs.Count > 0) { // remove jobs as we handle them... IJobDetail detail = jobs[0]; jobs.Remove(detail); IJobDetail dupeJ = null; try { // The existing job could have been deleted, and Quartz API doesn't allow us to query this without // loading the job class, so use try/catch to handle it. dupeJ = sched.GetJobDetail(detail.Key); } catch (JobPersistenceException e) { if (e.InnerException is TypeLoadException && OverWriteExistingData) { // We are going to replace jobDetail anyway, so just delete it first. log.Info("Removing job: " + detail.Key); sched.DeleteJob(detail.Key); } else { throw; } } if ((dupeJ != null)) { if (!OverWriteExistingData && IgnoreDuplicates) { log.Info("Not overwriting existing job: " + dupeJ.Key); continue; // just ignore the entry } if (!OverWriteExistingData && !IgnoreDuplicates) { throw new ObjectAlreadyExistsException(detail); } } if (dupeJ != null) { log.Info("Replacing job: " + detail.Key); } else { log.Info("Adding job: " + detail.Key); } List <IMutableTrigger> triggersOfJob; triggersByFQJobName.TryGetValue(detail.Key, out triggersOfJob); if (!detail.Durable && (triggersOfJob == null || triggersOfJob.Count == 0)) { if (dupeJ == null) { throw new SchedulerException( "A new job defined without any triggers must be durable: " + detail.Key); } if ((dupeJ.Durable && (sched.GetTriggersOfJob(detail.Key).Count == 0))) { throw new SchedulerException( "Can't change existing durable job without triggers to non-durable: " + detail.Key); } } if (dupeJ != null || detail.Durable) { if (triggersOfJob != null && triggersOfJob.Count > 0) { sched.AddJob(detail, true, true); // add the job regardless is durable or not b/c we have trigger to add } else { sched.AddJob(detail, true, false); // add the job only if a replacement or durable, else exception will throw! } } else { bool addJobWithFirstSchedule = true; // Add triggers related to the job... while (triggersOfJob.Count > 0) { IMutableTrigger trigger = triggersOfJob[0]; // remove triggers as we handle them... triggersOfJob.Remove(trigger); ITrigger dupeT = sched.GetTrigger(trigger.Key); if (dupeT != null) { if (OverWriteExistingData) { if (log.IsDebugEnabled) { log.DebugFormat("Rescheduling job: {0} with updated trigger: {1}", trigger.JobKey, trigger.Key); } } else if (IgnoreDuplicates) { log.Info("Not overwriting existing trigger: " + dupeT.Key); continue; // just ignore the trigger (and possibly job) } else { throw new ObjectAlreadyExistsException(trigger); } if (!dupeT.JobKey.Equals(trigger.JobKey)) { log.WarnFormat("Possibly duplicately named ({0}) triggers in jobs xml file! ", trigger.Key); } DoRescheduleJob(sched, trigger, dupeT); } else { if (log.IsDebugEnabled) { log.DebugFormat("Scheduling job: {0} with trigger: {1}", trigger.JobKey, trigger.Key); } try { if (addJobWithFirstSchedule) { sched.ScheduleJob(detail, trigger); // add the job if it's not in yet... addJobWithFirstSchedule = false; } else { sched.ScheduleJob(trigger); } } catch (ObjectAlreadyExistsException) { if (log.IsDebugEnabled) { log.DebugFormat("Adding trigger: {0} for job: {1} failed because the trigger already existed. " + "This is likely due to a race condition between multiple instances " + "in the cluster. Will try to reschedule instead.", trigger.Key, detail.Key); } // Let's try one more time as reschedule. DoRescheduleJob(sched, trigger, sched.GetTrigger(trigger.Key)); } } } } } // add triggers that weren't associated with a new job... (those we already handled were removed above) foreach (IMutableTrigger trigger in triggers) { ITrigger dupeT = sched.GetTrigger(trigger.Key); if (dupeT != null) { if (OverWriteExistingData) { if (log.IsDebugEnabled) { log.DebugFormat("Rescheduling job: " + trigger.JobKey + " with updated trigger: " + trigger.Key); } } else if (IgnoreDuplicates) { log.Info("Not overwriting existing trigger: " + dupeT.Key); continue; // just ignore the trigger } else { throw new ObjectAlreadyExistsException(trigger); } if (!dupeT.JobKey.Equals(trigger.JobKey)) { log.WarnFormat("Possibly duplicately named ({0}) triggers in jobs xml file! ", trigger.Key); } DoRescheduleJob(sched, trigger, dupeT); } else { if (log.IsDebugEnabled) { log.DebugFormat("Scheduling job: {0} with trigger: {1}", trigger.JobKey, trigger.Key); } try { sched.ScheduleJob(trigger); } catch (ObjectAlreadyExistsException) { if (log.IsDebugEnabled) { log.Debug( "Adding trigger: " + trigger.Key + " for job: " + trigger.JobKey + " failed because the trigger already existed. " + "This is likely due to a race condition between multiple instances " + "in the cluster. Will try to reschedule instead."); } // Let's rescheduleJob one more time. DoRescheduleJob(sched, trigger, sched.GetTrigger(trigger.Key)); } } } }
/// <summary> /// Schedules the given sets of jobs and triggers. /// </summary> /// <param name="sched">The sched.</param> public virtual void ScheduleJobs(IScheduler sched) { List <IJobDetail> jobs = new List <IJobDetail>(LoadedJobs); List <ITrigger> triggers = new List <ITrigger>(LoadedTriggers); IDictionary <JobKey, List <IMutableTrigger> > triggersByFQJobName = BuildTriggersByFQJobNameMap(triggers); // add each job, and it's associated triggers while (jobs.Count > 0) { // remove jobs as we handle them... IJobDetail detail = jobs[0]; jobs.Remove(detail); IJobDetail dupeJ = sched.GetJobDetail(detail.Key); if ((dupeJ != null)) { if (!OverWriteExistingData && IgnoreDuplicates) { continue; // just ignore the entry } if (!OverWriteExistingData && !IgnoreDuplicates) { throw new ObjectAlreadyExistsException(detail); } } if (dupeJ != null) { } else { } List <IMutableTrigger> triggersOfJob; triggersByFQJobName.TryGetValue(detail.Key, out triggersOfJob); if (!detail.Durable && (triggersOfJob == null || triggersOfJob.Count == 0)) { if (dupeJ == null) { throw new SchedulerException( "A new job defined without any triggers must be durable: " + detail.Key); } if ((dupeJ.Durable && (sched.GetTriggersOfJob(detail.Key).Count == 0))) { throw new SchedulerException( "Can't change existing durable job without triggers to non-durable: " + detail.Key); } } if (dupeJ != null || detail.Durable) { sched.AddJob(detail, true); // add the job if a replacement or durable } else { bool addJobWithFirstSchedule = true; // Add triggers related to the job... while (triggersOfJob.Count > 0) { IMutableTrigger trigger = triggersOfJob[0]; // remove triggers as we handle them... triggersOfJob.Remove(trigger); ITrigger dupeT = sched.GetTrigger(trigger.Key); if (dupeT != null) { if (OverWriteExistingData) { } else if (IgnoreDuplicates) { continue; // just ignore the trigger (and possibly job) } else { throw new ObjectAlreadyExistsException(trigger); } if (!dupeT.JobKey.Equals(trigger.JobKey)) { } sched.RescheduleJob(trigger.Key, trigger); } else { try { if (addJobWithFirstSchedule) { sched.ScheduleJob(detail, trigger); // add the job if it's not in yet... addJobWithFirstSchedule = false; } else { sched.ScheduleJob(trigger); } } catch (ObjectAlreadyExistsException) { // Let's try one more time as reschedule. sched.RescheduleJob(trigger.Key, trigger); } } } } } // add triggers that weren't associated with a new job... (those we already handled were removed above) foreach (IMutableTrigger trigger in triggers) { ITrigger dupeT = sched.GetTrigger(trigger.Key); if (dupeT != null) { if (OverWriteExistingData) { } else if (IgnoreDuplicates) { continue; // just ignore the trigger } else { throw new ObjectAlreadyExistsException(trigger); } if (!dupeT.JobKey.Equals(trigger.JobKey)) { } sched.RescheduleJob(trigger.Key, trigger); } else { try { sched.ScheduleJob(trigger); } catch (ObjectAlreadyExistsException) { // Let's rescheduleJob one more time. sched.RescheduleJob(trigger.Key, trigger); } } } }