/// <summary> /// Trigger the identified <see cref="IJob" /> (Execute it /// now) - with a volatile trigger. /// </summary> public virtual void TriggerJobWithVolatileTrigger(SchedulingContext ctxt, string jobName, string groupName, JobDataMap data) { ValidateState(); if (groupName == null) { groupName = SchedulerConstants.DefaultGroup; } Trigger trig = new SimpleTrigger(NewTriggerId(), SchedulerConstants.DefaultManualTriggers, jobName, groupName, DateTime.UtcNow, null, 0, TimeSpan.Zero); trig.Volatile = true; trig.ComputeFirstFireTimeUtc(null); if (data != null) { trig.JobDataMap = data; } bool collision = true; while (collision) { try { resources.JobStore.StoreTrigger(ctxt, trig, false); collision = false; } catch (ObjectAlreadyExistsException) { trig.Name = NewTriggerId(); } } NotifySchedulerThread(trig.GetNextFireTimeUtc()); NotifySchedulerListenersScheduled(trig); }
/// <summary> /// Insert the simple trigger data. /// </summary> /// <param name="conn">The DB Connection.</param> /// <param name="trigger">The trigger to insert.</param> /// <returns>The number of rows inserted.</returns> public virtual int InsertSimpleTrigger(ConnectionAndTransactionHolder conn, SimpleTrigger trigger) { using (IDbCommand cmd = PrepareCommand(conn, ReplaceTablePrefix(SqlInsertSimpleTrigger))) { AddCommandParameter(cmd, 1, "triggerName", trigger.Name); AddCommandParameter(cmd, 2, "triggerGroup", trigger.Group); AddCommandParameter(cmd, 3, "triggerRepeatCount", trigger.RepeatCount); AddCommandParameter(cmd, 4, "triggerRepeatInterval", trigger.RepeatInterval.TotalMilliseconds); AddCommandParameter(cmd, 5, "triggerTimesTriggered", trigger.TimesTriggered); return cmd.ExecuteNonQuery(); } }
/// <summary> /// Select all of the triggers for jobs that are requesting recovery. The /// returned trigger objects will have unique "recoverXXX" trigger names and /// will be in the <see cref="SchedulerConstants.DefaultRecoveryGroup" /> /// trigger group. /// </summary> /// <remarks> /// In order to preserve the ordering of the triggers, the fire time will be /// set from the <i>ColumnFiredTime</i> column in the <i>TableFiredTriggers</i> /// table. The caller is responsible for calling <see cref="Trigger.ComputeFirstFireTimeUtc" /> /// on each returned trigger. It is also up to the caller to insert the /// returned triggers to ensure that they are fired. /// </remarks> /// <param name="conn">The DB Connection</param> /// <returns> an array of <see cref="Trigger" /> objects</returns> public virtual Trigger[] SelectTriggersForRecoveringJobs(ConnectionAndTransactionHolder conn) { ArrayList list = new ArrayList(); using ( IDbCommand cmd = PrepareCommand(conn, ReplaceTablePrefix(SqlSelectInstancesRecoverableFiredTriggers))) { AddCommandParameter(cmd, 1, "instanceName", instanceId); AddCommandParameter(cmd, 2, "requestsRecovery", GetDbBooleanValue(true)); using (IDataReader rs = cmd.ExecuteReader()) { long dumId = DateTime.UtcNow.Ticks; while (rs.Read()) { string jobName = GetString(rs[ColumnJobName]); string jobGroup = GetString(rs[ColumnJobGroup]); // string trigName = GetString(rs[ColumnTriggerName]); // string trigGroup = GetString(rs[ColumnTriggerGroup]); long firedTimeInTicks = Convert.ToInt64(rs[ColumnFiredTime], CultureInfo.InvariantCulture); int priority = Convert.ToInt32(rs[ColumnPriority], CultureInfo.InvariantCulture); DateTime firedTime = new DateTime(firedTimeInTicks); SimpleTrigger rcvryTrig = new SimpleTrigger("recover_" + instanceId + "_" + Convert.ToString(dumId++, CultureInfo.InvariantCulture), SchedulerConstants.DefaultRecoveryGroup, firedTime); rcvryTrig.JobName = jobName; rcvryTrig.JobGroup = jobGroup; rcvryTrig.Priority = priority; rcvryTrig.MisfireInstruction = MisfireInstruction.SimpleTrigger.FireNow; list.Add(rcvryTrig); } } } // read JobDataMaps with different reader.. foreach (SimpleTrigger trigger in list) { JobDataMap jd = SelectTriggerJobDataMap(conn, trigger.Name, trigger.Group); jd.Put(SchedulerConstants.FailedJobOriginalTriggerName, trigger.Name); jd.Put(SchedulerConstants.FailedJobOriginalTriggerGroup, trigger.Group); jd.Put(SchedulerConstants.FailedJobOriginalTriggerFiretimeInMillisecoonds, Convert.ToString(trigger.StartTimeUtc, CultureInfo.InvariantCulture)); trigger.JobDataMap = jd; } object[] oArr = list.ToArray(); Trigger[] tArr = new Trigger[oArr.Length]; Array.Copy(oArr, 0, tArr, 0, oArr.Length); return tArr; }
/// <summary> /// Select a trigger. /// </summary> /// <param name="conn">the DB Connection</param> /// <param name="triggerName">the name of the trigger</param> /// <param name="groupName">the group containing the trigger</param> /// <returns>The <see cref="Trigger" /> object</returns> public virtual Trigger SelectTrigger(ConnectionAndTransactionHolder conn, string triggerName, string groupName) { Trigger trigger = null; string jobName = null; string jobGroup = null; bool volatility = false; string description = null; string triggerType = ""; string calendarName = null; int misFireInstr = Int32.MinValue; int priority = Int32.MinValue; IDictionary map = null; NullableDateTime pft = null; NullableDateTime endTimeD = null; NullableDateTime nft = null; DateTime startTimeD = DateTime.MinValue; using (IDbCommand cmd = PrepareCommand(conn, ReplaceTablePrefix(SqlSelectTrigger))) { AddCommandParameter(cmd, 1, "triggerName", triggerName); AddCommandParameter(cmd, 2, "triggerGroup", groupName); using (IDataReader rs = cmd.ExecuteReader()) { if (rs.Read()) { jobName = GetString(rs[ColumnJobName]); jobGroup = GetString(rs[ColumnJobGroup]); volatility = GetBoolean(rs[ColumnIsVolatile]); description = GetString(rs[ColumnDescription]); long nextFireTime = Convert.ToInt64(rs[ColumnNextFireTime], CultureInfo.InvariantCulture); long prevFireTime = Convert.ToInt64(rs[ColumnPreviousFireTime], CultureInfo.InvariantCulture); triggerType = GetString(rs[ColumnTriggerType]); long startTime = Convert.ToInt64(rs[ColumnStartTime], CultureInfo.InvariantCulture); long endTime = Convert.ToInt64(rs[ColumnEndTime], CultureInfo.InvariantCulture); calendarName = GetString(rs[ColumnCalendarName]); misFireInstr = Convert.ToInt32(rs[ColumnMifireInstruction], CultureInfo.InvariantCulture); priority = Convert.ToInt32(rs[ColumnPriority], CultureInfo.InvariantCulture); if (CanUseProperties) { map = GetMapFromProperties(rs, 15); } else { map = (IDictionary)GetObjectFromBlob(rs, 15); } if (nextFireTime > 0) { nft = new DateTime(nextFireTime); } if (prevFireTime > 0) { pft = new DateTime(prevFireTime); } startTimeD = new DateTime(startTime); if (endTime > 0) { endTimeD = new DateTime(endTime); } // done reading rs.Close(); if (triggerType.Equals(TriggerTypeSimple)) { using (IDbCommand cmd2 = PrepareCommand(conn, ReplaceTablePrefix(SqlSelectSimpleTrigger))) { AddCommandParameter(cmd2, 1, "triggerName", triggerName); AddCommandParameter(cmd2, 2, "triggerGroup", groupName); using (IDataReader rs2 = cmd2.ExecuteReader()) { if (rs2.Read()) { int repeatCount = Convert.ToInt32(rs2[ColumnRepeatCount], CultureInfo.InvariantCulture); long repeatInterval = Convert.ToInt64(rs2[ColumnRepeatInterval], CultureInfo.InvariantCulture); int timesTriggered = Convert.ToInt32(rs2[ColumnTimesTriggered], CultureInfo.InvariantCulture); SimpleTrigger st = new SimpleTrigger(triggerName, groupName, jobName, jobGroup, startTimeD, endTimeD, repeatCount, TimeSpan.FromMilliseconds(repeatInterval)); st.CalendarName = calendarName; st.MisfireInstruction = misFireInstr; st.TimesTriggered = timesTriggered; st.Volatile = volatility; st.SetNextFireTime(nft); st.SetPreviousFireTime(pft); st.Description = description; st.Priority = priority; if (null != map) { st.JobDataMap = new JobDataMap(map); } trigger = st; } } } } else if (triggerType.Equals(TriggerTypeCron)) { using (IDbCommand cmd2 = PrepareCommand(conn, ReplaceTablePrefix(SqlSelectCronTriggers))) { AddCommandParameter(cmd2, 1, "triggerName", triggerName); AddCommandParameter(cmd2, 2, "triggerGroup", groupName); using (IDataReader rs2 = cmd2.ExecuteReader()) { if (rs2.Read()) { string cronExpr = GetString(rs2[ColumnCronExpression]); string timeZoneId = GetString(rs2[ColumnTimeZoneId]); CronTrigger ct = null; try { TimeZone timeZone = null; if (timeZoneId != null) { #if NET_35 timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId); #endif } ct = new CronTrigger(triggerName, groupName, jobName, jobGroup, startTimeD, endTimeD, cronExpr, timeZone); } catch (Exception ex) { logger.Warn("Got error from expression, still continuing", ex); // expr must be valid, or it never would have // gotten to the store... } if (null != ct) { ct.CalendarName = calendarName; ct.MisfireInstruction = misFireInstr; ct.Volatile = volatility; ct.SetNextFireTime(nft); ct.SetPreviousFireTime(pft); ct.Description = description; if (null != map) { ct.JobDataMap = new JobDataMap(map); } trigger = ct; } } } } } else if (triggerType.Equals(TriggerTypeBlob)) { using (IDbCommand cmd2 = PrepareCommand(conn, ReplaceTablePrefix(SqlSelectBlobTrigger))) { AddCommandParameter(cmd2, 1, "triggerName", triggerName); AddCommandParameter(cmd2, 2, "triggerGroup", groupName); using (IDataReader rs2 = cmd2.ExecuteReader()) { if (rs2.Read()) { trigger = (Trigger)GetObjectFromBlob(rs2, 2); } } } } else { throw new Exception("Class for trigger type '" + triggerType + "' not found."); } } } } return trigger; }
/// <summary> /// Make a trigger that will fire every N hours, with the given number of /// repeats. /// <p> /// The generated trigger will not have its name, group, /// or end-time set. The Start time defaults to 'now'. /// </p> /// </summary> /// <param name="intervalInHours">the number of hours between firings</param> /// <param name="repeatCount">the number of times to repeat the firing</param> /// <returns>the new trigger</returns> public static Trigger MakeHourlyTrigger(int intervalInHours, int repeatCount) { SimpleTrigger trig = new SimpleTrigger(); trig.RepeatInterval = TimeSpan.FromHours(intervalInHours); trig.RepeatCount = repeatCount; trig.StartTimeUtc = DateTime.UtcNow; return trig; }
/// <summary> /// Make a trigger that will fire <param name="repeatCount" /> times, waiting /// <param name="repeatInterval" /> between each fire. /// </summary> /// <remarks> /// The generated trigger will not have its name, group, /// or end-time set. The Start time defaults to 'now'. /// </remarks> /// <returns>the newly created trigger</returns> public static Trigger MakeImmediateTrigger(int repeatCount, TimeSpan repeatInterval) { SimpleTrigger trig = new SimpleTrigger(); trig.StartTimeUtc = DateTime.UtcNow; trig.RepeatCount = repeatCount; trig.RepeatInterval = repeatInterval; return trig; }