Пример #1
0
		/// <summary>
		/// Create a JobRunShell instance with the given settings.
		/// </summary>
		/// <param name="jobRunShellFactory">A handle to the <see cref="IJobRunShellFactory" /> that produced
		/// this <see cref="JobRunShell" />.</param>
		/// <param name="scheduler">The <see cref="IScheduler" /> instance that should be made
		/// available within the <see cref="JobExecutionContext" />.</param>
		/// <param name="schdCtxt">the <see cref="SchedulingContext" /> that should be used by the
		/// <see cref="JobRunShell" /> when making updates to the <see cref="IJobStore" />.</param>
		public JobRunShell(IJobRunShellFactory jobRunShellFactory, IScheduler scheduler, SchedulingContext schdCtxt)
		{
			this.jobRunShellFactory = jobRunShellFactory;
			this.scheduler = scheduler;
			this.schdCtxt = schdCtxt;
            log = LogManager.GetLogger(GetType());
		}
Пример #2
0
		/// <summary>
		/// Get all of the Triggers that are associated to the given Job.
		/// <p>
		/// If there are no matches, a zero-length array should be returned.
		/// </p>
		/// </summary>
		public virtual Trigger[] GetTriggersForJob(SchedulingContext ctxt, string jobName, string groupName)
		{
			ArrayList trigList = new ArrayList();

			string jobKey = JobWrapper.GetJobNameKey(jobName, groupName);
			lock (triggerLock)
			{
				for (int i = 0; i < triggers.Count; i++)
				{
					TriggerWrapper tw = (TriggerWrapper) triggers[i];
					if (tw.jobKey.Equals(jobKey))
					{
						trigList.Add(tw.trigger.Clone());
					}
				}
			}

			return (Trigger[]) trigList.ToArray(typeof (Trigger));
		}
Пример #3
0
        /// <summary>
        /// Pause all of the <see cref="Trigger" />s in the given group.
        /// </summary>
        public virtual void PauseTriggerGroup(SchedulingContext ctxt, string groupName)
        {
            ValidateState();

            if (groupName == null)
            {
                groupName = SchedulerConstants.DefaultGroup;
            }

            resources.JobStore.PauseTriggerGroup(ctxt, groupName);
            NotifySchedulerThread(null);
            NotifySchedulerListenersPausedTrigger(null, groupName);
        }
Пример #4
0
        /// <summary>
        /// Remove (delete) the <see cref="Trigger" /> with the
        /// given name, and store the new given one - which must be associated
        /// with the same job.
        /// </summary>
        /// <param name="ctxt">The scheduling context.</param>
        /// <param name="triggerName">The name of the <see cref="Trigger" /> to be removed.</param>
        /// <param name="groupName">The group name of the <see cref="Trigger" /> to be removed.</param>
        /// <param name="newTrigger">The new <see cref="Trigger" /> to be stored.</param>
        /// <returns>
        /// 	<see langword="null" /> if a <see cref="Trigger" /> with the given
        /// name and group was not found and removed from the store, otherwise
        /// the first fire time of the newly scheduled trigger.
        /// </returns>
        public virtual NullableDateTime RescheduleJob(SchedulingContext ctxt, string triggerName, string groupName, Trigger newTrigger)
        {
            ValidateState();

            if (groupName == null)
            {
                groupName = SchedulerConstants.DefaultGroup;
            }

            newTrigger.Validate();

            ICalendar cal = null;
            if (newTrigger.CalendarName != null)
            {
                cal = resources.JobStore.RetrieveCalendar(ctxt, newTrigger.CalendarName);
            }

            NullableDateTime ft = newTrigger.ComputeFirstFireTimeUtc(cal);

            if (!ft.HasValue)
            {
                throw new SchedulerException("Based on configured schedule, the given trigger will never fire.",
                                             SchedulerException.ErrorClientError);
            }

            if (resources.JobStore.ReplaceTrigger(ctxt, triggerName, groupName, newTrigger))
            {
                NotifySchedulerThread(newTrigger.GetNextFireTimeUtc());
                NotifySchedulerListenersUnscheduled(triggerName, groupName);
                NotifySchedulerListenersScheduled(newTrigger);
            }
            else
            {
                return null;
            }

            return ft;
        }
Пример #5
0
        /// <summary>
        /// Delete the identified <see cref="IJob" /> from the Scheduler - and any
        /// associated <see cref="Trigger" />s.
        /// </summary>
        /// <returns> true if the Job was found and deleted.</returns>
        public virtual bool DeleteJob(SchedulingContext ctxt, string jobName, string groupName)
        {
            ValidateState();

            if (groupName == null)
            {
                groupName = SchedulerConstants.DefaultGroup;
            }

            return resources.JobStore.RemoveJob(ctxt, jobName, groupName);
        }
Пример #6
0
        /// <summary>
        /// Schedule the given <see cref="Trigger" /> with the
        /// <see cref="IJob" /> identified by the <see cref="Trigger" />'s settings.
        /// </summary>
        public virtual DateTime ScheduleJob(SchedulingContext ctxt, Trigger trigger)
        {
            ValidateState();

            if (trigger == null)
            {
                throw new SchedulerException("Trigger cannot be null",
                        SchedulerException.ErrorClientError);
            }

            trigger.Validate();

            ICalendar cal = null;
            if (trigger.CalendarName != null)
            {
                cal = resources.JobStore.RetrieveCalendar(ctxt, trigger.CalendarName);
                if (cal == null)
                {
                    throw new SchedulerException(string.Format(CultureInfo.InvariantCulture, "Calendar not found: {0}", trigger.CalendarName),
                                                 SchedulerException.ErrorPersistenceCalendarDoesNotExist);
                }
            }

            NullableDateTime ft = trigger.ComputeFirstFireTimeUtc(cal);

            if (!ft.HasValue)
            {
                throw new SchedulerException("Based on configured schedule, the given trigger will never fire.",
                                             SchedulerException.ErrorClientError);
            }

            resources.JobStore.StoreTrigger(ctxt, trigger, false);
            NotifySchedulerThread(trigger.GetNextFireTimeUtc());
            NotifySchedulerListenersScheduled(trigger);

            return ft.Value;
        }
Пример #7
0
        /// <summary>
        /// Create a <see cref="SchedulerScheduler" /> with the given configuration
        /// properties.
        /// </summary>
        /// <seealso cref="SchedulerSchedulerResources" />
        public SchedulerScheduler(SchedulerSchedulerResources resources, SchedulingContext ctxt, TimeSpan idleWaitTime, TimeSpan dbRetryInterval)
        {
            Log = LogManager.GetLogger(GetType());
            this.resources = resources;
            try
            {
                Bind();
            }
            catch (Exception re)
            {
                throw new SchedulerException("Unable to bind scheduler to remoting context.", re);
            }

            schedThread = new SchedulerSchedulerThread(this, resources, ctxt);
            if (idleWaitTime > TimeSpan.Zero)
            {
                schedThread.IdleWaitTime = idleWaitTime;
            }
            if (dbRetryInterval > TimeSpan.Zero)
            {
                schedThread.DbFailureRetryInterval = dbRetryInterval;
            }

            jobMgr = new ExecutingJobsManager();
            AddGlobalJobListener(jobMgr);
            errLogger = new ErrorLogger();
            AddSchedulerListener(errLogger);

            signaler = new SchedulerSignalerImpl(this, this.schedThread);

            Log.Info(string.Format(CultureInfo.InvariantCulture, "Scheduler Scheduler v.{0} created.", Version));
        }
Пример #8
0
        /// <summary>
        /// Interrupt all instances of the identified InterruptableJob.
        /// </summary>
        public virtual bool Interrupt(SchedulingContext ctxt, string jobName, string groupName)
        {
            if (groupName == null)
            {
                groupName = SchedulerConstants.DefaultGroup;
            }

            IList jobs = CurrentlyExecutingJobs;

            JobDetail jobDetail;

            bool interrupted = false;

            foreach (JobExecutionContext jec in jobs)
            {
                jobDetail = jec.JobDetail;
                if (jobName.Equals(jobDetail.Name) && groupName.Equals(jobDetail.Group))
                {
                    IJob job = jec.JobInstance;
                    if (job is IInterruptableJob)
                    {
                        ((IInterruptableJob)job).Interrupt();
                        interrupted = true;
                    }
                    else
                    {
                        throw new UnableToInterruptJobException(string.Format(CultureInfo.InvariantCulture, "Job '{0}' of group '{1}' can not be interrupted, since it does not implement {2}", jobName, groupName, typeof(IInterruptableJob).FullName));
                    }
                }
            }

            return interrupted;
        }
Пример #9
0
        /// <summary> 
        /// Get all <see cref="Trigger" /> s that are associated with the
        /// identified <see cref="JobDetail" />.
        /// </summary>
        public virtual Trigger[] GetTriggersOfJob(SchedulingContext ctxt, string jobName, string groupName)
        {
            ValidateState();

            if (groupName == null)
            {
                groupName = SchedulerConstants.DefaultGroup;
            }

            return resources.JobStore.GetTriggersForJob(ctxt, jobName, groupName);
        }
Пример #10
0
        /// <summary>
        /// Resume (un-pause) all triggers - equivalent of calling <see cref="ResumeTriggerGroup(SchedulingContext, string)" />
        /// on every group.
        /// <p>
        /// If any <see cref="Trigger" /> missed one or more fire-times, then the
        /// <see cref="Trigger" />'s misfire instruction will be applied.
        /// </p>
        /// </summary>
        /// <seealso cref="PauseAll(SchedulingContext)" />
        public virtual void ResumeAll(SchedulingContext ctxt)
        {
            ValidateState();

            resources.JobStore.ResumeAll(ctxt);
            NotifySchedulerThread(null);
            NotifySchedulerListenersResumedTrigger(null, null);
        }
Пример #11
0
        /// <summary>
        /// Resume (un-pause) all of the <see cref="JobDetail" />s
        /// in the given group.
        /// <p>
        /// If any of the <see cref="IJob" /> s had <see cref="Trigger" /> s that
        /// missed one or more fire-times, then the <see cref="Trigger" />'s
        /// misfire instruction will be applied.
        /// </p>
        /// </summary>
        public virtual void ResumeJobGroup(SchedulingContext ctxt, string groupName)
        {
            ValidateState();

            if (groupName == null)
            {
                groupName = SchedulerConstants.DefaultGroup;
            }

            resources.JobStore.ResumeJobGroup(ctxt, groupName);
            NotifySchedulerThread(null);
            NotifySchedulerListenersResumedJob(null, groupName);
        }
Пример #12
0
 /// <summary>
 /// Gets the paused trigger groups.
 /// </summary>
 /// <param name="ctxt">The the job scheduling context.</param>
 /// <returns></returns>
 public virtual ISet GetPausedTriggerGroups(SchedulingContext ctxt)
 {
     return resources.JobStore.GetPausedTriggerGroups(ctxt);
 }
Пример #13
0
		/// <summary> 
		/// Pause the <see cref="JobDetail" /> with the given
		/// name - by pausing all of its current <see cref="Trigger" />s.
		/// </summary>
		public virtual void PauseJob(SchedulingContext ctxt, string jobName, string groupName)
		{
            lock (triggerLock)
			{
				Trigger[] t = GetTriggersForJob(ctxt, jobName, groupName);
				for (int j = 0; j < t.Length; j++)
				{
					PauseTrigger(ctxt, t[j].Name, t[j].Group);
				}
			}
		}
Пример #14
0
		/// <summary>
		/// Pause all of the <see cref="Trigger" />s in the given group.
		/// <p>
		/// The JobStore should "remember" that the group is paused, and impose the
		/// pause on any new triggers that are added to the group while the group is
		/// paused.
		/// </p>
		/// </summary>
		public virtual void PauseTriggerGroup(SchedulingContext ctxt, string groupName)
		{
            lock (triggerLock)
			{
				if (pausedTriggerGroups.Contains(groupName))
				{
					return;
				}
				pausedTriggerGroups.Add(groupName);
				string[] names = GetTriggerNames(ctxt, groupName);

				for (int i = 0; i < names.Length; i++)
				{
					PauseTrigger(ctxt, names[i], groupName);
				}
			}
		}
Пример #15
0
		/// <summary> 
		/// Pause the <see cref="Trigger" /> with the given name.
		/// </summary>
		public virtual void PauseTrigger(SchedulingContext ctxt, string triggerName, string groupName)
		{
			TriggerWrapper tw = (TriggerWrapper) triggersByFQN[TriggerWrapper.GetTriggerNameKey(triggerName, groupName)];

			// does the trigger exist?
			if (tw == null || tw.trigger == null)
			{
				return;
			}
			// if the trigger is "complete" pausing it does not make sense...
            if (tw.state == InternalTriggerState.Complete)
			{
				return;
			}

			lock (triggerLock)
			{
                if (tw.state == InternalTriggerState.Blocked)
				{
                    tw.state = InternalTriggerState.PausedAndBlocked;
				}
				else
				{
                    tw.state = InternalTriggerState.Paused;
				}
				timeTriggers.Remove(tw);
			}
		}
Пример #16
0
 /// <summary>
 /// Get the names of all registered <see cref="ICalendar" />s.
 /// </summary>
 public virtual string[] GetCalendarNames(SchedulingContext ctxt)
 {
     ValidateState();
     return resources.JobStore.GetCalendarNames(ctxt);
 }
Пример #17
0
 /// <summary>
 /// Notifies the job store job complete.
 /// </summary>
 /// <param name="ctxt">The job scheduling context.</param>
 /// <param name="trigger">The trigger.</param>
 /// <param name="detail">The detail.</param>
 /// <param name="instCode">The instruction code.</param>
 protected internal virtual void NotifyJobStoreJobComplete(SchedulingContext ctxt, Trigger trigger, JobDetail detail,
                                                           SchedulerInstruction instCode)
 {
     resources.JobStore.TriggeredJobComplete(ctxt, trigger, detail, instCode);
 }
Пример #18
0
 /// <summary>
 /// Get the names of all known <see cref="Trigger" />
 /// groups.
 /// </summary>
 public virtual string[] GetTriggerGroupNames(SchedulingContext ctxt)
 {
     ValidateState();
     return resources.JobStore.GetTriggerGroupNames(ctxt);
 }
Пример #19
0
 public bool IsTriggerGroupPaused(SchedulingContext ctxt, string groupName)
 {
     return resources.JobStore.IsTriggerGroupPaused(ctxt, groupName);
 }
Пример #20
0
        /// <summary>
        /// Get the names of all the <see cref="Trigger" />s in
        /// the given group.
        /// </summary>
        public virtual string[] GetTriggerNames(SchedulingContext ctxt, string groupName)
        {
            ValidateState();

            if (groupName == null)
            {
                groupName = SchedulerConstants.DefaultGroup;
            }

            return resources.JobStore.GetTriggerNames(ctxt, groupName);
        }
Пример #21
0
        /// <summary> 
        /// Add the <see cref="IJob" /> identified by the given
        /// <see cref="JobDetail" /> to the Scheduler, and
        /// associate the given <see cref="Trigger" /> with it.
        /// <p>
        /// If the given Trigger does not reference any <see cref="IJob" />, then it
        /// will be set to reference the Job passed with it into this method.
        /// </p>
        /// </summary>
        public virtual DateTime ScheduleJob(SchedulingContext ctxt, JobDetail jobDetail, Trigger trigger)
        {
            ValidateState();


            if (jobDetail == null)
            {
                throw new SchedulerException("JobDetail cannot be null",
                        SchedulerException.ErrorClientError);
            }

            if (trigger == null)
            {
                throw new SchedulerException("Trigger cannot be null",
                        SchedulerException.ErrorClientError);
            }

            jobDetail.Validate();

            if (trigger.JobName == null)
            {
                trigger.JobName = jobDetail.Name;
                trigger.JobGroup = jobDetail.Group;
            }
            else if (trigger.JobName != null && !trigger.JobName.Equals(jobDetail.Name))
            {
                throw new SchedulerException("Trigger does not reference given job!", SchedulerException.ErrorClientError);
            }
            else if (trigger.JobGroup != null && !trigger.JobGroup.Equals(jobDetail.Group))
            {
                throw new SchedulerException("Trigger does not reference given job!", SchedulerException.ErrorClientError);
            }

            trigger.Validate();

            ICalendar cal = null;
            if (trigger.CalendarName != null)
            {
                cal = resources.JobStore.RetrieveCalendar(ctxt, trigger.CalendarName);
                if (cal == null)
                {
                    throw new SchedulerException(string.Format(CultureInfo.InvariantCulture, "Calendar not found: {0}", trigger.CalendarName),
                                                 SchedulerException.ErrorPersistenceCalendarDoesNotExist);
                }
            }

            NullableDateTime ft = trigger.ComputeFirstFireTimeUtc(cal);

            if (!ft.HasValue)
            {
                throw new SchedulerException("Based on configured schedule, the given trigger will never fire.",
                                             SchedulerException.ErrorClientError);
            }

            resources.JobStore.StoreJobAndTrigger(ctxt, jobDetail, trigger);
            NotifySchedulerThread(trigger.GetNextFireTimeUtc());
            NotifySchedulerListenersScheduled(trigger);

            return ft.Value;
        }
Пример #22
0
        /// <summary> 
        /// Get the <see cref="JobDetail" /> for the <see cref="IJob" />
        /// instance with the given name and group.
        /// </summary>
        public virtual JobDetail GetJobDetail(SchedulingContext ctxt, string jobName, string jobGroup)
        {
            ValidateState();

            if (jobGroup == null)
            {
                jobGroup = SchedulerConstants.DefaultGroup;
            }

            return resources.JobStore.RetrieveJob(ctxt, jobName, jobGroup);
        }
Пример #23
0
        /// <summary>
        /// Add the given <see cref="IJob" /> to the Scheduler - with no associated
        /// <see cref="Trigger" />. The <see cref="IJob" /> will be 'dormant' until
        /// it is scheduled with a <see cref="Trigger" />, or <see cref="IScheduler.TriggerJob(string ,string)" />
        /// is called for it.
        /// <p>
        /// The <see cref="IJob" /> must by definition be 'durable', if it is not,
        /// SchedulerException will be thrown.
        /// </p>
        /// </summary>
        public virtual void AddJob(SchedulingContext ctxt, JobDetail jobDetail, bool replace)
        {
            ValidateState();

            if (!jobDetail.Durable && !replace)
            {
                throw new SchedulerException("Jobs added with no trigger must be durable.", SchedulerException.ErrorClientError);
            }

            resources.JobStore.StoreJob(ctxt, jobDetail, replace);
        }
Пример #24
0
        /// <summary>
        /// Get the current state of the identified <see cref="Trigger" />.  
        /// </summary>
        /// <seealso cref="TriggerState.Normal" />
        /// <seealso cref="TriggerState.Paused" />
        /// <seealso cref="TriggerState.Complete" />
        /// <seealso cref="TriggerState.Error" />      
        public virtual TriggerState GetTriggerState(SchedulingContext ctxt, string triggerName, string triggerGroup)
        {
            ValidateState();

            if (triggerGroup == null)
            {
                triggerGroup = SchedulerConstants.DefaultGroup;
            }

            return resources.JobStore.GetTriggerState(ctxt, triggerName, triggerGroup);
        }
Пример #25
0
        /// <summary>
        /// Remove the indicated <see cref="Trigger" /> from the
        /// scheduler.
        /// </summary>
        public virtual bool UnscheduleJob(SchedulingContext ctxt, string triggerName, string groupName)
        {
            ValidateState();

            if (groupName == null)
            {
                groupName = SchedulerConstants.DefaultGroup;
            }

            if (resources.JobStore.RemoveTrigger(ctxt, triggerName, groupName))
            {
                NotifySchedulerThread(null);
                NotifySchedulerListenersUnscheduled(triggerName, groupName);
            }
            else
            {
                return false;
            }

            return true;
        }
Пример #26
0
 /// <summary>
 /// Add (register) the given <see cref="ICalendar" /> to the Scheduler.
 /// </summary>
 public virtual void AddCalendar(SchedulingContext ctxt, string calName, ICalendar calendar, bool replace,
                                 bool updateTriggers)
 {
     ValidateState();
     resources.JobStore.StoreCalendar(ctxt, calName, calendar, replace, updateTriggers);
 }
Пример #27
0
        /// <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);
        }
Пример #28
0
 /// <summary>
 /// Delete the identified <see cref="ICalendar" /> from the Scheduler.
 /// </summary>
 /// <returns> true if the Calendar was found and deleted.</returns>
 public virtual bool DeleteCalendar(SchedulingContext ctxt, string calName)
 {
     ValidateState();
     return resources.JobStore.RemoveCalendar(ctxt, calName);
 }
Пример #29
0
 /// <summary> 
 /// Get the <see cref="ICalendar" /> instance with the given name.
 /// </summary>
 public virtual ICalendar GetCalendar(SchedulingContext ctxt, string calName)
 {
     ValidateState();
     return resources.JobStore.RetrieveCalendar(ctxt, calName);
 }
Пример #30
0
		/// <summary>
		/// Get the names of all of the <see cref="Trigger" /> groups.
		/// </summary>
		public virtual string[] GetTriggerGroupNames(SchedulingContext ctxt)
		{
			string[] outList;

			lock (triggerLock)
			{
				outList = new string[triggersByGroup.Count];
				int outListPos = 0;
				IEnumerator keys = new HashSet(triggersByGroup.Keys).GetEnumerator();
				while (keys.MoveNext())
				{
					outList[outListPos++] = ((string) keys.Current);
				}
			}

			return outList;
		}