/// <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());
		}
 /// <summary>
 /// Construct a new <see cref="QuartzSchedulerThread" /> for the given
 /// <see cref="QuartzScheduler" /> as a non-daemon <see cref="Thread" />
 /// with normal priority.
 /// </summary>
 internal QuartzSchedulerThread(QuartzScheduler qs, QuartzSchedulerResources qsRsrcs, SchedulingContext ctxt)
     : this(qs, qsRsrcs, ctxt, qsRsrcs.MakeSchedulerThreadDaemon, (int)ThreadPriority.Normal)
 {
 }
        /// <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>
        /// 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;
        }
        /// <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);
        }
        /// <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;
        }
 public bool IsTriggerGroupPaused(SchedulingContext ctxt, string groupName)
 {
     return resources.JobStore.IsTriggerGroupPaused(ctxt, groupName);
 }
 /// <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);
 }
        /// <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);
        }
        /// <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);
        }
 /// <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);
 }
 /// <summary>
 /// Stores the given <see cref="JobDetail" />.
 /// </summary>
 /// <param name="ctxt"></param>
 /// <param name="newJob">The <see cref="JobDetail" /> to be stored.</param>
 /// <param name="replaceExisting">
 /// If <see langword="true" />, any <see cref="IJob" /> existing in the
 /// <see cref="IJobStore" /> with the same name &amp; group should be over-written.
 /// </param>
 public void StoreJob(SchedulingContext ctxt, JobDetail newJob, bool replaceExisting)
 {
     ExecuteInLock(
         (LockOnInsert || replaceExisting) ? LockTriggerAccess : null,
         new StoreJobCallback(this, ctxt, newJob, replaceExisting));
 }
 public StoreJobAndTriggerCallback(JobStoreSupport js, JobDetail newJob, Trigger newTrigger,
                                   SchedulingContext ctxt)
     : base(js)
 {
     this.newJob = newJob;
     this.newTrigger = newTrigger;
     this.ctxt = ctxt;
 }
 /// <summary>
 /// returns true if the given TriggerGroup
 /// is paused
 /// </summary>
 /// <param name="ctxt"></param>
 /// <param name="groupName"></param>
 /// <returns></returns>
 public bool IsTriggerGroupPaused(SchedulingContext ctxt, string groupName)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 /// Construct a <see cref="RemoteScheduler" /> instance to proxy the given
 /// RemoteableQuartzScheduler instance, and with the given
 /// <see cref="SchedulingContext" />.
 /// </summary>
 public RemoteScheduler(SchedulingContext schedCtxt, string schedId)
 {
     this.schedCtxt = schedCtxt;
     this.schedId = schedId;
 }
 /// <summary>
 /// Store the given <see cref="JobDetail" /> and <see cref="Trigger" />.
 /// </summary>
 /// <param name="ctxt">SchedulingContext</param>
 /// <param name="newJob">Job to be stored.</param>
 /// <param name="newTrigger">Trigger to be stored.</param>
 public void StoreJobAndTrigger(SchedulingContext ctxt, JobDetail newJob, Trigger newTrigger)
 {
     ExecuteInLock((LockOnInsert) ? LockTriggerAccess : null,
                   new StoreJobAndTriggerCallback(this, newJob, newTrigger, ctxt));
 }
        /// <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);
        }
        /// <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;
        }
 /// <summary>
 /// Get the names of all known <see cref="Trigger" />
 /// groups.
 /// </summary>
 public virtual string[] GetTriggerGroupNames(SchedulingContext ctxt)
 {
     ValidateState();
     return resources.JobStore.GetTriggerGroupNames(ctxt);
 }
        /// <summary>
        /// Create a <see cref="QuartzScheduler" /> with the given configuration
        /// properties.
        /// </summary>
        /// <seealso cref="QuartzSchedulerResources" />
        public QuartzScheduler(QuartzSchedulerResources 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 QuartzSchedulerThread(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, "Quartz Scheduler v.{0} created.", Version));
        }
        /// <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);
        }
        /// <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;
        }
        /// <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);
        }
        /// <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);
        }
        /// <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);
        }
        /// <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;
        }
 /// <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);
 }
        /// <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);
        }
 /// <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);
 }
        /// <summary>
        /// Construct a new <see cref="QuartzSchedulerThread" /> for the given
        /// <see cref="QuartzScheduler" /> as a <see cref="Thread" /> with the given
        /// attributes.
        /// </summary>
        internal QuartzSchedulerThread(QuartzScheduler qs, QuartzSchedulerResources qsRsrcs, SchedulingContext ctxt,
                                       bool setDaemon, int threadPrio) : base(qsRsrcs.ThreadName)
        {
            log = LogManager.GetLogger(GetType());
            //ThreadGroup generatedAux = qs.SchedulerThreadGroup;
            this.qs      = qs;
            this.qsRsrcs = qsRsrcs;
            this.ctxt    = ctxt;
            IsBackground = setDaemon;
            Priority     = (ThreadPriority)threadPrio;

            // start the underlying thread, but put this object into the 'paused'
            // state
            // so processing doesn't start yet...
            paused = true;
            halted = false;
            Start();
        }
 /// <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);
 }
Exemplo n.º 32
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());
 }
 /// <summary>
 /// Get the names of all registered <see cref="ICalendar" />s.
 /// </summary>
 public virtual string[] GetCalendarNames(SchedulingContext ctxt)
 {
     ValidateState();
     return resources.JobStore.GetCalendarNames(ctxt);
 }