예제 #1
0
        /// <summary>
        /// Adds the service job history.
        /// </summary>
        /// <param name="job">The job.</param>
        /// <param name="rockContext">The rock context.</param>
        private void AddServiceJobHistory(ServiceJob job, RockContext rockContext)
        {
            var jobHistoryService = new ServiceJobHistoryService(rockContext);
            var jobHistory        = new ServiceJobHistory()
            {
                ServiceJobId  = job.Id,
                StartDateTime = job.LastRunDateTime?.AddSeconds(0.0d - ( double )job.LastRunDurationSeconds),
                StopDateTime  = job.LastRunDateTime,
                Status        = job.LastStatus,
                StatusMessage = job.LastStatusMessage,
                ServiceWorker = Environment.MachineName.ToLower()
            };

            jobHistoryService.Add(jobHistory);
            rockContext.SaveChanges();
        }
        /// <summary>
        /// Starts the job scheduler.
        /// </summary>
        private static void StartJobScheduler()
        {
            using (var rockContext = new RockContext())
            {
                // create scheduler
                ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
                QuartzScheduler = schedulerFactory.GetScheduler();

                // get list of active jobs
                ServiceJobService jobService = new ServiceJobService(rockContext);
                var activeJobList            = jobService.GetActiveJobs().OrderBy(a => a.Name).ToList();
                foreach (ServiceJob job in activeJobList)
                {
                    const string ErrorLoadingStatus = "Error Loading Job";

                    try
                    {
                        IJobDetail jobDetail  = jobService.BuildQuartzJob(job);
                        ITrigger   jobTrigger = jobService.BuildQuartzTrigger(job);

                        // Schedule the job (unless the cron expression is set to never run for an on-demand job like rebuild streaks)
                        if (job.CronExpression != ServiceJob.NeverScheduledCronExpression)
                        {
                            QuartzScheduler.ScheduleJob(jobDetail, jobTrigger);
                        }

                        //// if the last status was an error, but we now loaded successful, clear the error
                        // also, if the last status was 'Running', clear that status because it would have stopped if the app restarted
                        if (job.LastStatus == ErrorLoadingStatus || job.LastStatus == "Running")
                        {
                            job.LastStatusMessage = string.Empty;
                            job.LastStatus        = string.Empty;
                            rockContext.SaveChanges();
                        }
                    }
                    catch (Exception exception)
                    {
                        // create a friendly error message
                        string message = $"Error loading the job: {job.Name}.\n\n{exception.Message}";

                        // log the error
                        var startupException = new RockStartupException(message, exception);

                        LogError(startupException, null);

                        job.LastStatusMessage = message;
                        job.LastStatus        = ErrorLoadingStatus;
                        job.LastStatus        = ErrorLoadingStatus;
                        rockContext.SaveChanges();

                        var jobHistoryService = new ServiceJobHistoryService(rockContext);
                        var jobHistory        = new ServiceJobHistory()
                        {
                            ServiceJobId  = job.Id,
                            StartDateTime = RockDateTime.Now,
                            StopDateTime  = RockDateTime.Now,
                            Status        = job.LastStatus,
                            StatusMessage = job.LastStatusMessage
                        };

                        jobHistoryService.Add(jobHistory);
                        rockContext.SaveChanges();
                    }
                }

                // set up the listener to report back from jobs as they complete
                QuartzScheduler.ListenerManager.AddJobListener(new RockJobListener(), EverythingMatcher <JobKey> .AllJobs());

                // set up a trigger listener that can prevent a job from running if another scheduler is
                // already running it (i.e., someone running it manually).
                QuartzScheduler.ListenerManager.AddTriggerListener(new RockTriggerListener(), EverythingMatcher <JobKey> .AllTriggers());

                // start the scheduler
                QuartzScheduler.Start();
            }
        }
예제 #3
0
        /// <summary>
        /// Handles the RowDataBound event of the gScheduledJobHistory control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.GridViewRowEventArgs"/> instance containing the event data.</param>
        protected void gScheduledJobHistory_RowDataBound(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
        {
            var site = RockPage.Site;

            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                ServiceJobHistory serviceJobHistory = e.Row.DataItem as ServiceJobHistory;
                if (serviceJobHistory == null)
                {
                    return;
                }

                // format duration
                if (serviceJobHistory.DurationSeconds.HasValue)
                {
                    int      durationSeconds = serviceJobHistory.DurationSeconds.Value;
                    TimeSpan duration        = TimeSpan.FromSeconds(durationSeconds);

                    var lDurationSeconds = e.Row.FindControl("lDurationSeconds") as Literal;

                    if (lDurationSeconds != null)
                    {
                        if (duration.Days > 0)
                        {
                            lDurationSeconds.Text = duration.TotalHours.ToString("F2") + " hours";
                        }
                        else if (duration.Hours > 0)
                        {
                            lDurationSeconds.Text = String.Format("{0:%h}h {0:%m}m {0:%s}s", duration);
                        }
                        else if (duration.Minutes > 0)
                        {
                            lDurationSeconds.Text = String.Format("{0:%m}m {0:%s}s", duration);
                        }
                        else
                        {
                            lDurationSeconds.Text = String.Format("{0:%s}s", duration);
                        }
                    }
                }

                // format last status
                var lStatus = e.Row.FindControl("lStatus") as Literal;
                if (lStatus != null)
                {
                    string status = serviceJobHistory.Status ?? string.Empty;

                    switch (status)
                    {
                    case "Success":
                        lStatus.Text = "<span class='label label-success'>Success</span>";
                        break;

                    case "Running":
                        lStatus.Text = "<span class='label label-info'>Running</span>";
                        break;

                    case "Exception":
                        lStatus.Text = "<span class='label label-danger'>Failed</span>";
                        break;

                    case "Warning":
                        lStatus.Text = "<span class='label label-warning'>Warning</span>";
                        break;

                    case "":
                        lStatus.Text = "";
                        break;

                    default:
                        lStatus.Text = String.Format("<span class='label label-warning'>{0}</span>", status);
                        break;
                    }

                    var lStatusMessageAsHtml = e.Row.FindControl("lStatusMessageAsHtml") as Literal;
                    if (lStatusMessageAsHtml != null)
                    {
                        lStatusMessageAsHtml.Text = serviceJobHistory.StatusMessageAsHtml;
                    }
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Executes this instance.
        /// </summary>
        public void Execute()
        {
            using (var rockContext = new RockContext())
            {
                var jobService = new ServiceJobService(rockContext);

                ServiceJob job = jobService.Get(JobId);
                if (job != null)
                {
                    try
                    {
                        // create a scheduler specific for the job
                        var scheduleConfig      = new System.Collections.Specialized.NameValueCollection();
                        var runNowSchedulerName = ("RunNow:" + job.Guid.ToString("N")).Truncate(40);
                        scheduleConfig.Add(StdSchedulerFactory.PropertySchedulerInstanceName, runNowSchedulerName);
                        var schedulerFactory = new StdSchedulerFactory(scheduleConfig);
                        var sched            = new StdSchedulerFactory(scheduleConfig).GetScheduler();
                        if (sched.IsStarted)
                        {
                            // the job is currently running as a RunNow job
                            return;
                        }

                        // create the quartz job and trigger
                        IJobDetail jobDetail  = jobService.BuildQuartzJob(job);
                        var        jobTrigger = TriggerBuilder.Create()
                                                .WithIdentity(job.Guid.ToString(), job.Name)
                                                .StartNow()
                                                .Build();

                        // schedule the job
                        sched.ScheduleJob(jobDetail, jobTrigger);

                        // set up the listener to report back from the job when it completes
                        sched.ListenerManager.AddJobListener(new RockJobListener(), EverythingMatcher <JobKey> .AllJobs());

                        // start the scheduler
                        sched.Start();

                        // Wait 10secs to give job chance to start
                        System.Threading.Tasks.Task.Delay(new TimeSpan(0, 0, 10)).Wait();

                        // stop the scheduler when done with job
                        sched.Shutdown(true);
                    }

                    catch (Exception ex)
                    {
                        // create a friendly error message
                        ExceptionLogService.LogException(ex, null);
                        string message = string.Format("Error doing a 'Run Now' on job: {0}. \n\n{2}", job.Name, job.Assembly, ex.Message);
                        job.LastStatusMessage = message;
                        job.LastStatus        = "Error Loading Job";
                        rockContext.SaveChanges();

                        var jobHistoryService = new ServiceJobHistoryService(rockContext);
                        var jobHistory        = new ServiceJobHistory()
                        {
                            ServiceJobId  = job.Id,
                            StartDateTime = RockDateTime.Now,
                            StopDateTime  = RockDateTime.Now,
                            Status        = job.LastStatus,
                            StatusMessage = job.LastStatusMessage
                        };
                        jobHistoryService.Add(jobHistory);
                        rockContext.SaveChanges();
                    }
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Executes this instance.
        /// </summary>
        public void Execute()
        {
            using (var rockContext = new RockContext())
            {
                var jobService = new ServiceJobService(rockContext);

                ServiceJob job = jobService.Get(JobId);
                if (job != null)
                {
                    try
                    {
                        // create a scheduler specific for the job
                        var scheduleConfig      = new System.Collections.Specialized.NameValueCollection();
                        var runNowSchedulerName = ("RunNow:" + job.Guid.ToString("N")).Truncate(40);
                        scheduleConfig.Add(StdSchedulerFactory.PropertySchedulerInstanceName, runNowSchedulerName);
                        var schedulerFactory = new StdSchedulerFactory(scheduleConfig);
                        var sched            = new StdSchedulerFactory(scheduleConfig).GetScheduler();
                        if (sched.IsStarted)
                        {
                            // the job is currently running as a RunNow job
                            return;
                        }

                        // Check if another scheduler is running this job
                        try
                        {
                            var otherSchedulers = new Quartz.Impl.StdSchedulerFactory().AllSchedulers
                                                  .Where(s => s.SchedulerName != runNowSchedulerName);

                            foreach (var scheduler in otherSchedulers)
                            {
                                if (scheduler.GetCurrentlyExecutingJobs().Where(j => j.JobDetail.Description == JobId.ToString() &&
                                                                                j.JobDetail.ConcurrentExectionDisallowed).Any())
                                {
                                    // A job with that Id is already running and ConcurrentExectionDisallowed is true
                                    System.Diagnostics.Debug.WriteLine(RockDateTime.Now.ToString() + $" Scheduler '{scheduler.SchedulerName}' is already executing job Id '{JobId}' (name: {job.Name})");
                                    return;
                                }
                            }
                        }
                        catch { }

                        // create the quartz job and trigger
                        IJobDetail jobDetail = jobService.BuildQuartzJob(job);

                        if (_jobDataMapDictionary != null)
                        {
                            // Force the <string, string> dictionary so that within Jobs, it is always okay to use
                            // JobDataMap.GetString(). This mimics Rock attributes always being stored as strings.
                            // If we allow non-strings, like integers, then JobDataMap.GetString() throws an exception.
                            jobDetail.JobDataMap.PutAll(_jobDataMapDictionary.ToDictionary(kvp => kvp.Key, kvp => ( object )kvp.Value));
                        }

                        var jobTrigger = TriggerBuilder.Create()
                                         .WithIdentity(job.Guid.ToString(), job.Name)
                                         .StartNow()
                                         .Build();

                        // schedule the job
                        sched.ScheduleJob(jobDetail, jobTrigger);

                        // set up the listener to report back from the job when it completes
                        sched.ListenerManager.AddJobListener(new RockJobListener(), EverythingMatcher <JobKey> .AllJobs());

                        // start the scheduler
                        sched.Start();

                        // Wait 10secs to give job chance to start
                        System.Threading.Tasks.Task.Delay(new TimeSpan(0, 0, 10)).Wait();

                        // stop the scheduler when done with job
                        sched.Shutdown(true);
                    }

                    catch (Exception ex)
                    {
                        // create a friendly error message
                        ExceptionLogService.LogException(ex, null);
                        string message = string.Format("Error doing a 'Run Now' on job: {0}. \n\n{2}", job.Name, job.Assembly, ex.Message);
                        job.LastStatusMessage = message;
                        job.LastStatus        = "Error Loading Job";
                        rockContext.SaveChanges();

                        var jobHistoryService = new ServiceJobHistoryService(rockContext);
                        var jobHistory        = new ServiceJobHistory()
                        {
                            ServiceJobId  = job.Id,
                            StartDateTime = RockDateTime.Now,
                            StopDateTime  = RockDateTime.Now,
                            Status        = job.LastStatus,
                            StatusMessage = job.LastStatusMessage
                        };
                        jobHistoryService.Add(jobHistory);
                        rockContext.SaveChanges();
                    }
                }
            }
        }