public void TestAcquireNextTrigger() { DateTimeOffset d = DateBuilder.EvenMinuteDateAfterNow(); IOperableTrigger trigger1 = new SimpleTriggerImpl("trigger1", "triggerGroup1", fJobDetail.Name, fJobDetail.Group, d.AddSeconds(200), d.AddSeconds(200), 2, TimeSpan.FromSeconds(2)); IOperableTrigger trigger2 = new SimpleTriggerImpl("trigger2", "triggerGroup1", fJobDetail.Name, fJobDetail.Group, d.AddSeconds(50), d.AddSeconds(200), 2, TimeSpan.FromSeconds(2)); IOperableTrigger trigger3 = new SimpleTriggerImpl("trigger1", "triggerGroup2", fJobDetail.Name, fJobDetail.Group, d.AddSeconds(100), d.AddSeconds(200), 2, TimeSpan.FromSeconds(2)); trigger1.ComputeFirstFireTimeUtc(null); trigger2.ComputeFirstFireTimeUtc(null); trigger3.ComputeFirstFireTimeUtc(null); fJobStore.StoreTrigger(trigger1, false); fJobStore.StoreTrigger(trigger2, false); fJobStore.StoreTrigger(trigger3, false); DateTimeOffset firstFireTime = trigger1.GetNextFireTimeUtc().Value; Assert.AreEqual(0, fJobStore.AcquireNextTriggers(d.AddMilliseconds(10), 1, TimeSpan.Zero).Count); Assert.AreEqual(trigger2, fJobStore.AcquireNextTriggers(firstFireTime.AddSeconds(10), 1, TimeSpan.Zero)[0]); Assert.AreEqual(trigger3, fJobStore.AcquireNextTriggers(firstFireTime.AddSeconds(10), 1, TimeSpan.Zero)[0]); Assert.AreEqual(trigger1, fJobStore.AcquireNextTriggers(firstFireTime.AddSeconds(10), 1, TimeSpan.Zero)[0]); Assert.AreEqual(0, fJobStore.AcquireNextTriggers(firstFireTime.AddSeconds(10), 1, TimeSpan.Zero).Count); // release trigger3 fJobStore.ReleaseAcquiredTrigger(trigger3); Assert.AreEqual(trigger3, fJobStore.AcquireNextTriggers(firstFireTime.AddSeconds(10), 1, TimeSpan.FromMilliseconds(1))[0]); }
public void TestClone() { SimpleTriggerImpl simpleTrigger = new SimpleTriggerImpl(); // Make sure empty sub-objects are cloned okay ITrigger clone = (ITrigger) simpleTrigger.Clone(); Assert.AreEqual(0, clone.JobDataMap.Count); // Make sure non-empty sub-objects are cloned okay simpleTrigger.JobDataMap.Put("K1", "V1"); simpleTrigger.JobDataMap.Put("K2", "V2"); clone = (ITrigger) simpleTrigger.Clone(); Assert.AreEqual(2, clone.JobDataMap.Count); Assert.AreEqual("V1", clone.JobDataMap.Get("K1")); Assert.AreEqual("V2", clone.JobDataMap.Get("K2")); // Make sure sub-object collections have really been cloned by ensuring // their modification does not change the source Trigger clone.JobDataMap.Remove("K1"); Assert.AreEqual(1, clone.JobDataMap.Count); Assert.AreEqual(2, simpleTrigger.JobDataMap.Count); Assert.AreEqual("V1", simpleTrigger.JobDataMap.Get("K1")); Assert.AreEqual("V2", simpleTrigger.JobDataMap.Get("K2")); }
public static void Main(string[] args) { // XmlConfigurator.Configure(); var properties = new NameValueCollection(); properties["quartz.scheduler.instanceName"] = "ServerScheduler"; // set thread pool info properties["quartz.threadPool.threadCount"] = "0"; // set remoting expoter properties["quartz.scheduler.proxy"] = "true"; properties["quartz.scheduler.proxy.address"] = "tcp://localhost:555/QuartzScheduler"; var scheduleFactory = new StdSchedulerFactory(properties); scheduler = scheduleFactory.GetScheduler(); var md = scheduler.GetMetaData(); scheduler.Start(); IJobDetail job = JobBuilder.Create<Jobs.SimpleJob>().Build(); ITrigger jobTrigger = new SimpleTriggerImpl("TenSecondTrigger", 20, new TimeSpan(0, 0, 0, 5)); //Periodic scheduling scheduler.ScheduleJob(job,jobTrigger); //Trigger a job from elsewhere without a trigger for one time var jobKey = job.Key; var jobDataMap = job.JobDataMap; scheduler.TriggerJob(jobKey,jobDataMap); }
public void TestSameDefaultPriority() { NameValueCollection config = new NameValueCollection(); config["quartz.threadPool.threadCount"] = "1"; config["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool"; IScheduler sched = new StdSchedulerFactory(config).GetScheduler(); DateTime n = DateTime.UtcNow; DateTime cal = new DateTime(n.Year, n.Month, n.Day, n.Hour, n.Minute, 1, n.Millisecond); IMutableTrigger trig1 = new SimpleTriggerImpl("T1", null, cal); IMutableTrigger trig2 = new SimpleTriggerImpl("T2", null, cal); JobDetailImpl jobDetail = new JobDetailImpl("JD", null, typeof (TestJob)); sched.ScheduleJob(jobDetail, trig1); trig2.JobKey = new JobKey(jobDetail.Key.Name); sched.ScheduleJob(trig2); sched.Start(); Thread.Sleep(2000); Assert.AreEqual("T1T2", result.ToString()); sched.Shutdown(); }
private void StartJob(JobDefinition job) { this.EventReporter.Trace("Creating job: " + job.JobName); if(job.Schedule is JobCronSchedule) { } else if(job.Schedule is JobSimpleSchedule) { var type = this.TypeLoader.LoadType(job.AssemblyName, job.ClassName); var genericJobWrapperType = typeof(JobWrapper<,>); var combinedJobType = genericJobWrapperType.MakeGenericType(type); var jobDetail = new JobDetailImpl(job.JobName, combinedJobType); var simpleSchedule = (JobSimpleSchedule)job.Schedule; ITrigger trigger; if (simpleSchedule.DelayStartMinutes != 0) { trigger = new SimpleTriggerImpl(job.JobName + "Trigger", DateBuilder.FutureDate(simpleSchedule.DelayStartMinutes,IntervalUnit.Minute), null, SimpleTriggerImpl.RepeatIndefinitely, TimeSpan.FromMinutes(simpleSchedule.IntervalMinutes)); } else { trigger = new SimpleTriggerImpl(job.JobName + "Trigger", null, SimpleTriggerImpl.RepeatIndefinitely, TimeSpan.FromMinutes(simpleSchedule.IntervalMinutes)); } this.Scheduler.ScheduleJob(jobDetail, trigger); } this.EventReporter.Trace("Done Creating " + job.JobName); }
public override bool OnStart() { Trace.WriteLine("WorkerRole1 Run", "Information"); var properties = new NameValueCollection(); properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz"; properties["quartz.jobStore.dataSource"] = "default"; properties["quartz.jobStore.clustered"] = "true"; properties["quartz.jobStore.selectWithLockSQL"] = string.Format(CultureInfo.InvariantCulture, "SELECT * FROM {0}{1} WHERE {2} = {3} AND {4} = @lockName", new object[] { "{0}", "LOCKS", "SCHED_NAME", "{1}", "LOCK_NAME" }); properties["quartz.jobStore.acquireTriggersWithinLock"] = "true"; properties["quartz.scheduler.instanceId"] = "AUTO"; properties["quartz.threadPool.threadCount"] = "1"; properties["quartz.jobStore.tablePrefix"] = "Scheduling."; properties["quartz.dataSource.default.connectionString"] = @"Server = (local)\sqlexpress; Database = DB; Integrated Security = True"; properties["quartz.dataSource.default.provider"] = "SqlServer-20"; var scheduler = new StdSchedulerFactory(properties).GetScheduler(); scheduler.Clear(); var triggerKey = new TriggerKey("t1"); var trigger = scheduler.GetTrigger(triggerKey); var jobBuilder = JobBuilder.Create<Job>(); var job = jobBuilder.Build(); var t = scheduler.GetTrigger(new TriggerKey("t1")); trigger = new SimpleTriggerImpl("t1", 100000, TimeSpan.FromSeconds(5)); scheduler.ScheduleJob(job, trigger); scheduler.Start(); return base.OnStart(); }
public override ISchedule CreateSchedule(ScheduleType scheduleType, string name, IDictionary<string, object> parameters) { switch (scheduleType) { case ScheduleType.Periodic: var triggerSettings = new PeriodicScheduleParameters(parameters); var trigger = new SimpleTriggerImpl { Name = name, RepeatCount = triggerSettings.RepeatCount, StartTimeUtc = triggerSettings.Start, RepeatInterval = triggerSettings.Interval }; return new TriggerWrapper(trigger, scheduleType); case ScheduleType.CronBased: var triggerSettingsCron = new CronScheduleParameters(parameters); var triggerCron = new CronTriggerImpl { Name = name, CronExpressionString = triggerSettingsCron.CronString }; return new TriggerWrapper(triggerCron, scheduleType); default: throw new Exception("Unsupported schedule type " + scheduleType.ToString()); } }
public void TestCreateJobInstance_SimpleDefaults() { IOperableTrigger trigger = new SimpleTriggerImpl(); TriggerFiredBundle bundle = TestUtil.CreateMinimalFiredBundleWithTypedJobDetail(typeof (NoOpJob), trigger); IJob job = factory.NewJob(bundle, null); Assert.IsNotNull(job, "Created job was null"); }
private void ScheduleImport(string Filename, int ImportDelay) { var startTime = new DateTimeOffset(DateTime.Now.AddMilliseconds(ImportDelay)); var jobTrigger = new SimpleTriggerImpl(Guid.NewGuid().ToString(), startTime); var jobDetails = new JobDetailImpl(Guid.NewGuid().ToString(), typeof(ImporterJob)); jobDetails.JobDataMap.Add("Filename", Filename); jobDetails.JobDataMap.Add("RetryCount", 0); Scheduler.ScheduleJob(jobDetails, jobTrigger); }
private void ScheduleRetryableJob(IJobExecutionContext context, IRetryableJob retryableJob) { var oldTrigger = context.Trigger; // Unschedule old trigger _scheduler.UnscheduleJob(oldTrigger.Key); // Create and schedule new trigge var retryTrigger = new SimpleTriggerImpl(oldTrigger.Key.Name, retryableJob.StartTimeRetryUtc, retryableJob.EndTimeRetryUtc, 0, TimeSpan.Zero); _scheduler.ScheduleJob(context.JobDetail, retryTrigger); }
static IOperableTrigger CreateTriggerCore(this IXpandJobTrigger jobTrigger, Type jobType) { IOperableTrigger trigger = null; if (jobTrigger is IXpandSimpleTrigger) trigger = new SimpleTriggerImpl(jobTrigger.Name, jobType.FullName); if (jobTrigger is IXpandCronTrigger) trigger = new CronTriggerImpl(jobTrigger.Name, jobType.FullName); if (trigger != null) { return trigger; } throw new NotImplementedException(jobTrigger.GetType().FullName); }
public static void Schedule() { ISchedulerFactory factory = new StdSchedulerFactory(); IScheduler schedule = factory.GetScheduler(); schedule.Start(); IJobDetail job = JobBuilder.Create<SynchronishJob>().WithIdentity("SynochronishOU", "JobGroup1").Build(); SimpleTriggerImpl trigger = new SimpleTriggerImpl(); trigger.RepeatInterval = new System.TimeSpan(2, 0, 0); trigger.StartTimeUtc = DateTime.UtcNow; trigger.Name = "Syn"; schedule.ScheduleJob(job, trigger); }
public void TestCreateJobInstance_IgnoredProperties() { factory.IgnoredUnknownProperties = new string[] {"foo", "baz"}; IOperableTrigger trigger = new SimpleTriggerImpl(); trigger.JobDataMap["foo"] = "should not be injected"; trigger.JobDataMap["number"] = 123; TriggerFiredBundle bundle = TestUtil.CreateMinimalFiredBundleWithTypedJobDetail(typeof(InjectableJob), trigger); InjectableJob job = (InjectableJob)factory.NewJob(bundle, null); Assert.IsNotNull(job, "Created job was null"); Assert.AreEqual(123, job.Number, "integer injection failed"); Assert.IsNull(job.Foo, "foo was injected when it was not supposed to "); }
public static SimpleTriggerImpl GetTriggerWithSecondOffset(int seconds) { SimpleTriggerImpl trigger = new SimpleTriggerImpl ( Triggers.RandomString(), //Random name because it has to be unique for a trigger type null, DateTime.UtcNow.AddSeconds(seconds), null, 0, TimeSpan.Zero ); return trigger; }
public static SimpleTriggerImpl GetTriggerAtDate(DateTime date) { SimpleTriggerImpl trigger = new SimpleTriggerImpl ( Triggers.RandomString(), //Random name because it has to be unique for a trigger type null, date, null, 0, TimeSpan.Zero ); return trigger; }
public void StartSchedule() { ISchedulerFactory schedFactory = new StdSchedulerFactory(); IScheduler scheduler = schedFactory.GetScheduler(); scheduler.Start(); IJobDetail jobDetail = new JobDetailImpl("myJob", null, typeof(DataJob)); jobDetail.JobDataMap["data"] = new ExternalData(); jobDetail.JobDataMap["dataManager"] = new DataManager(); jobDetail.JobDataMap["dbContext"] = new UowData(); ISimpleTrigger trigger = new SimpleTriggerImpl("myTrigger", null, DateTime.UtcNow, DateTime.UtcNow.AddYears(1), SimpleTriggerImpl.RepeatIndefinitely, TimeSpan.FromHours(2)); scheduler.ScheduleJob(jobDetail, trigger); }
/// <summary> /// Get the object to serialize when generating serialized file for future /// tests, and against which to validate deserialized object. /// </summary> /// <returns></returns> protected override object GetTargetObject() { JobDataMap jobDataMap = new JobDataMap(); jobDataMap.Put("A", "B"); SimpleTriggerImpl t = new SimpleTriggerImpl("SimpleTrigger", "SimpleGroup", "JobName", "JobGroup", StartTime, EndTime, 5, TimeSpan.FromSeconds(1)); t.CalendarName = "MyCalendar"; t.Description = "SimpleTriggerDesc"; t.JobDataMap = jobDataMap; t.MisfireInstruction = (MisfireInstruction.SimpleTrigger.RescheduleNextWithRemainingCount); return t; }
private void StartJob() { // http://stackoverflow.com/questions/1356789/how-to-use-quartz-net-with-asp-net var properties = new NameValueCollection(); properties["quartz.scheduler.proxy"] = "true"; properties["quartz.scheduler.proxy.address"] = "tcp://localhost:555/QuartzScheduler"; ISchedulerFactory schedulerFactory = new StdSchedulerFactory(properties); var scheduler = schedulerFactory.GetScheduler(); IJobDetail job = JobBuilder.Create<SimpleJob>().Build(); job.JobDataMap.Add("triggeredBy", "web"); ITrigger jobTrigger = new SimpleTriggerImpl("OneTimeTrigger", 1, new TimeSpan()); scheduler.ScheduleJob(job, jobTrigger); }
public void TestCreateJobInstance_SchedulerContextGiven() { IOperableTrigger trigger = new SimpleTriggerImpl(); TriggerFiredBundle bundle = TestUtil.CreateMinimalFiredBundleWithTypedJobDetail(typeof(InjectableJob), trigger); IDictionary<string, object> items = new Dictionary<string, object>(); items["foo"] = "bar"; items["number"] = 123; factory.SchedulerContext = new SchedulerContext(items); InjectableJob job = (InjectableJob)factory.NewJob(bundle, null); Assert.IsNotNull(job, "Created job was null"); Assert.AreEqual("bar", job.Foo, "string injection failed"); Assert.AreEqual(123, job.Number, "integer injection failed"); }
static IOperableTrigger CreateTriggerCore(this IXpandJobTrigger jobTrigger, Type jobType) { IOperableTrigger trigger = null; if (jobTrigger is IXpandSimpleTrigger) trigger = new SimpleTriggerImpl(jobTrigger.Name, jobType.FullName); if (jobTrigger is IXpandCronTrigger) trigger = new CronTriggerImpl(jobTrigger.Name, jobType.FullName); if (jobTrigger is INthIncludedDayTrigger) trigger = new NthIncludedDayTrigger(jobTrigger.Name, jobType.FullName); if (trigger != null) { // trigger.AddTriggerListener(new XpandTriggerListener().Name); return trigger; } throw new NotImplementedException(jobTrigger.GetType().FullName); }
public override void Run() { // This is a sample worker implementation. Replace with your logic. Trace.WriteLine("$projectname$ entry point called", "Information"); // Start init // construct job info IJobDetail jobDetail = new JobDetailImpl("myJob", null, typeof(TraceJob)); // fire every hour ITrigger trigger = new SimpleTriggerImpl("myTrigger", null, 3, new TimeSpan(0, 0, 10)); sched.ScheduleJob(jobDetail, trigger); // End init while (true) { Thread.Sleep(10000); Trace.WriteLine("Working", "Information"); } }
public void PauseJobGroupPausesNewJob() { string jobName1 = "PauseJobGroupPausesNewJob"; string jobName2 = "PauseJobGroupPausesNewJob2"; string jobGroup = "PauseJobGroupPausesNewJobGroup"; JobDetailImpl detail = new JobDetailImpl(jobName1, jobGroup, typeof (NoOpJob)); detail.Durable = true; fJobStore.StoreJob(detail, false); fJobStore.PauseJobs(GroupMatcher<JobKey>.GroupEquals(jobGroup)); detail = new JobDetailImpl(jobName2, jobGroup, typeof (NoOpJob)); detail.Durable = true; fJobStore.StoreJob(detail, false); string trName = "PauseJobGroupPausesNewJobTrigger"; string trGroup = "PauseJobGroupPausesNewJobTriggerGroup"; IOperableTrigger tr = new SimpleTriggerImpl(trName, trGroup, DateTimeOffset.UtcNow); tr.JobKey = new JobKey(jobName2, jobGroup); fJobStore.StoreTrigger(tr, false); Assert.AreEqual(TriggerState.Paused, fJobStore.GetTriggerState(tr.Key)); }
public void TestInvalidCalendarScheduling() { const string ExpectedError = "Calendar not found: FOOBAR"; ISchedulerFactory sf = new StdSchedulerFactory(); IScheduler sched = sf.GetScheduler(); DateTime runTime = DateTime.Now.AddMinutes(10); // define the job and tie it to our HelloJob class JobDetailImpl job = new JobDetailImpl("job1", "group1", typeof(NoOpJob)); // Trigger the job to run on the next round minute IOperableTrigger trigger = new SimpleTriggerImpl("trigger1", "group1", runTime); // set invalid calendar trigger.CalendarName = "FOOBAR"; try { sched.ScheduleJob(job, trigger); Assert.Fail("No error for non-existing calendar"); } catch (SchedulerException ex) { Assert.AreEqual(ExpectedError, ex.Message); } try { sched.ScheduleJob(trigger); Assert.Fail("No error for non-existing calendar"); } catch (SchedulerException ex) { Assert.AreEqual(ExpectedError, ex.Message); } sched.Shutdown(false); }
/// <summary> /// Trigger the identified <see cref="IJob" /> (Execute it now) - with a non-volatile trigger. /// </summary> public virtual void TriggerJob(JobKey jobKey, JobDataMap data) { ValidateState(); // TODO: use builder IOperableTrigger trig = new SimpleTriggerImpl( NewTriggerId(), SchedulerConstants.DefaultGroup, jobKey.Name, jobKey.Group, SystemTime.UtcNow(), null, 0, TimeSpan.Zero); trig.ComputeFirstFireTimeUtc(null); if (data != null) { trig.JobDataMap = data; } bool collision = true; while (collision) { try { resources.JobStore.StoreTrigger(trig, false); collision = false; } catch (ObjectAlreadyExistsException) { trig.Key = new TriggerKey(NewTriggerId(), SchedulerConstants.DefaultGroup); } } NotifySchedulerThread(trig.GetNextFireTimeUtc()); NotifySchedulerListenersScheduled(trig); }
public void TestSchedulingWhenUpdatingScheduleBasedOnExistingTrigger() { DateTimeOffset startTime = new DateTimeOffset(2012, 12, 30, 1, 0, 0, TimeSpan.Zero); DateTimeOffset previousFireTime = new DateTimeOffset(2013, 2, 15, 15, 0, 0, TimeSpan.Zero); SimpleTriggerImpl existing = new SimpleTriggerImpl("triggerToReplace", "groupToReplace", startTime, null, SimpleTriggerImpl.RepeatIndefinitely, TimeSpan.FromHours(1)); existing.JobKey = new JobKey("jobName1", "jobGroup1"); existing.SetPreviousFireTimeUtc(previousFireTime); existing.GetNextFireTimeUtc(); mockScheduler.Stub(x => x.GetTrigger(existing.Key)).Return(existing); Stream s = ReadJobXmlFromEmbeddedResource("ScheduleRelativeToOldTrigger.xml"); processor.ProcessStream(s, null); processor.ScheduleJobs(mockScheduler); // check that last fire time was taken from existing trigger mockScheduler.Stub(x => x.RescheduleJob(null, null)).IgnoreArguments(); var args = mockScheduler.GetArgumentsForCallsMadeOn(x => x.RescheduleJob(null, null)); ITrigger argumentTrigger = (ITrigger) args[0][1]; // replacement trigger should have same start time and next fire relative to old trigger's last fire time Assert.That(argumentTrigger, Is.Not.Null); Assert.That(argumentTrigger.StartTimeUtc, Is.EqualTo(startTime)); Assert.That(argumentTrigger.GetNextFireTimeUtc(), Is.EqualTo(previousFireTime.AddSeconds(10))); }
/// <summary> /// Called when the associated <see cref="IScheduler"/> is started, in order /// to let the plug-in know it can now make calls into the scheduler if it /// needs to. /// </summary> public virtual void Start() { try { if (jobFiles.Count > 0) { if (scanInterval > TimeSpan.Zero) { scheduler.Context.Put(JobInitializationPluginName + '_' + Name, this); } foreach (KeyValuePair<string, JobFile> pair in jobFiles) { JobFile jobFile = pair.Value; if (scanInterval > TimeSpan.Zero) { string jobTriggerName = BuildJobTriggerName(jobFile.FileBasename); TriggerKey tKey = new TriggerKey(jobTriggerName, JobInitializationPluginName); // remove pre-existing job/trigger, if any Scheduler.UnscheduleJob(tKey); // TODO: convert to use builder SimpleTriggerImpl trig = (SimpleTriggerImpl) Scheduler.GetTrigger(tKey); trig = new SimpleTriggerImpl(); trig.Name = (jobTriggerName); trig.Group = (JobInitializationPluginName); trig.StartTimeUtc = SystemTime.UtcNow(); trig.EndTimeUtc = (null); trig.RepeatCount = (SimpleTriggerImpl.RepeatIndefinitely); trig.RepeatInterval = (scanInterval); // TODO: convert to use builder JobDetailImpl job = new JobDetailImpl( jobTriggerName, JobInitializationPluginName, typeof (FileScanJob)); job.JobDataMap.Put(FileScanJob.FileName, jobFile.FilePath); job.JobDataMap.Put(FileScanJob.FileScanListenerName, JobInitializationPluginName + '_' + Name); scheduler.ScheduleJob(job, trig); Log.DebugFormat("Scheduled file scan job for data file: {0}, at interval: {1}", jobFile.FileName, scanInterval); } ProcessFile(jobFile); } } } catch (SchedulerException se) { Log.Error("Error starting background-task for watching jobs file.", se); } finally { started = true; } }
protected virtual void ClusterRecover(ConnectionAndTransactionHolder conn, IList<SchedulerStateRecord> failedInstances) { if (failedInstances.Count > 0) { long recoverIds = SystemTime.UtcNow().Ticks; LogWarnIfNonZero(failedInstances.Count, "ClusterManager: detected " + failedInstances.Count + " failed or restarted instances."); try { foreach (SchedulerStateRecord rec in failedInstances) { Log.Info("ClusterManager: Scanning for instance \"" + rec.SchedulerInstanceId + "\"'s failed in-progress jobs."); IList<FiredTriggerRecord> firedTriggerRecs = Delegate.SelectInstancesFiredTriggerRecords(conn, rec.SchedulerInstanceId); int acquiredCount = 0; int recoveredCount = 0; int otherCount = 0; Collection.HashSet<TriggerKey> triggerKeys = new Collection.HashSet<TriggerKey>(); foreach (FiredTriggerRecord ftRec in firedTriggerRecs) { TriggerKey tKey = ftRec.TriggerKey; JobKey jKey = ftRec.JobKey; triggerKeys.Add(tKey); // release blocked triggers.. if (ftRec.FireInstanceState.Equals(StateBlocked)) { Delegate.UpdateTriggerStatesForJobFromOtherState(conn, jKey, StateWaiting, StateBlocked); } else if (ftRec.FireInstanceState.Equals(StatePausedBlocked)) { Delegate.UpdateTriggerStatesForJobFromOtherState(conn, jKey, StatePaused, StatePausedBlocked); } // release acquired triggers.. if (ftRec.FireInstanceState.Equals(StateAcquired)) { Delegate.UpdateTriggerStateFromOtherState(conn, tKey, StateWaiting, StateAcquired); acquiredCount++; } else if (ftRec.JobRequestsRecovery) { // handle jobs marked for recovery that were not fully // executed.. if (JobExists(conn, jKey)) { SimpleTriggerImpl rcvryTrig = new SimpleTriggerImpl( "recover_" + rec.SchedulerInstanceId + "_" + Convert.ToString(recoverIds++, CultureInfo.InvariantCulture), SchedulerConstants.DefaultRecoveryGroup, ftRec.FireTimestamp); rcvryTrig.JobName = jKey.Name; rcvryTrig.JobGroup = jKey.Group; rcvryTrig.MisfireInstruction = MisfireInstruction.SimpleTrigger.FireNow; rcvryTrig.Priority = ftRec.Priority; JobDataMap jd = Delegate.SelectTriggerJobDataMap(conn, tKey); jd.Put(SchedulerConstants.FailedJobOriginalTriggerName, tKey.Name); jd.Put(SchedulerConstants.FailedJobOriginalTriggerGroup, tKey.Group); jd.Put(SchedulerConstants.FailedJobOriginalTriggerFiretimeInMillisecoonds, Convert.ToString(ftRec.FireTimestamp, CultureInfo.InvariantCulture)); rcvryTrig.JobDataMap = jd; rcvryTrig.ComputeFirstFireTimeUtc(null); StoreTrigger(conn, rcvryTrig, null, false, StateWaiting, false, true); recoveredCount++; } else { Log.Warn("ClusterManager: failed job '" + jKey + "' no longer exists, cannot schedule recovery."); otherCount++; } } else { otherCount++; } // free up stateful job's triggers if (ftRec.JobDisallowsConcurrentExecution) { Delegate.UpdateTriggerStatesForJobFromOtherState(conn, jKey, StateWaiting, StateBlocked); Delegate.UpdateTriggerStatesForJobFromOtherState(conn, jKey, StatePaused, StatePausedBlocked); } } Delegate.DeleteFiredTriggers(conn, rec.SchedulerInstanceId); // Check if any of the fired triggers we just deleted were the last fired trigger // records of a COMPLETE trigger. int completeCount = 0; foreach (TriggerKey triggerKey in triggerKeys) { if ( Delegate.SelectTriggerState(conn, triggerKey).Equals(StateComplete)) { IList<FiredTriggerRecord> firedTriggers = Delegate.SelectFiredTriggerRecords(conn, triggerKey.Name, triggerKey.Group); if (firedTriggers.Count == 0) { 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.SchedulerInstanceId.Equals(InstanceId) == false) { Delegate.DeleteSchedulerState(conn, rec.SchedulerInstanceId); } } } catch (Exception e) { throw new JobPersistenceException("Failure recovering jobs: " + e.Message, e); } } }
public void TestUpdateAfterMisfire() { DateTimeOffset startTime = new DateTimeOffset(2005, 7, 5, 9, 0, 0, TimeSpan.Zero); DateTimeOffset endTime = new DateTimeOffset(2005, 7, 5, 10, 0, 0, TimeSpan.Zero); SimpleTriggerImpl simpleTrigger = new SimpleTriggerImpl(); simpleTrigger.MisfireInstruction = MisfireInstruction.SimpleTrigger.RescheduleNowWithExistingRepeatCount; simpleTrigger.RepeatCount = 5; simpleTrigger.StartTimeUtc = startTime; simpleTrigger.EndTimeUtc = endTime; simpleTrigger.UpdateAfterMisfire(null); Assert.AreEqual(startTime, simpleTrigger.StartTimeUtc); Assert.AreEqual(endTime, simpleTrigger.EndTimeUtc.Value); Assert.IsTrue(!simpleTrigger.GetNextFireTimeUtc().HasValue); }
public void TestPrecision() { IOperableTrigger trigger = new SimpleTriggerImpl(); trigger.StartTimeUtc = new DateTimeOffset(1982, 6, 28, 13, 5, 5, 233, TimeSpan.Zero); Assert.IsTrue(trigger.HasMillisecondPrecision); Assert.AreEqual(233, trigger.StartTimeUtc.Millisecond); }
public void TestMisfireInstructionValidity() { SimpleTriggerImpl trigger = new SimpleTriggerImpl(); try { trigger.MisfireInstruction = MisfireInstruction.IgnoreMisfirePolicy; trigger.MisfireInstruction = MisfireInstruction.SmartPolicy; trigger.MisfireInstruction = MisfireInstruction.SimpleTrigger.FireNow; trigger.MisfireInstruction = MisfireInstruction.SimpleTrigger.RescheduleNextWithExistingCount; trigger.MisfireInstruction = MisfireInstruction.SimpleTrigger.RescheduleNextWithRemainingCount; trigger.MisfireInstruction = MisfireInstruction.SimpleTrigger.RescheduleNowWithExistingRepeatCount; trigger.MisfireInstruction = MisfireInstruction.SimpleTrigger.RescheduleNowWithRemainingRepeatCount; } catch (Exception) { Assert.Fail("Unexpected exception while setting misfire instruction."); } try { trigger.MisfireInstruction = MisfireInstruction.SimpleTrigger.RescheduleNextWithExistingCount + 1; Assert.Fail("Expected exception while setting invalid misfire instruction but did not get it."); } catch (Exception ex) { if (ex is AssertionException) { throw; } } }