Is it possible to run scheduled jobs only on weekdays and skip weekends?

Vote:
 

Hi

Is it possible to run scheduled jobs only on weekdays and skip weekends? So far, I don't see any setting that would allow that. Here's one way I can think of the schedule :

To start on Monday and run only for 5 days/week, so it will not run beyond Friday. But i'm not sure if it will get picked up again on Monday of next week? Would the scheduler be able to set next run date on Friday to Monday of next week?

Please advise.

Regards

Ritu

#210755
Dec 04, 2019 17:22
Vote:
 

This is not a out of the box feature. But of course you can do some customization.

Is this a custom Scheduled Job? If yes, you can do something like this

public override string Execute()
{
    var dayToday = DateTime.Now.DayOfWeek;
    if ((dayToday == DayOfWeek.Saturday) || (dayToday == DayOfWeek.Sunday))
    {
        this.Stop();
    }

    //// Your code goes here...

}

If that is not a customization, I am afraid there is a way to override that or not.

Thanks

#210757
Dec 04, 2019 20:37
Vote:
 

Hi Praful

Thanks for the suggestion. However, won't this still run the job first to check the day condition and then stop it on weekends, without going any further?

I guess if there is no other solution, this could be tried.

Regards

Ritu

#210758
Dec 04, 2019 20:42
willwon155 - Dec 18, 2019 7:23
Thanks, for giving peace of great information. And I am a pro developer in Canada if you want to reach more traffic on your page plz check out my website: Web Development Services
Vote:
 

Making small adjustments to Praful's code, I would:

public override string Execute()
{
   var dayOfWeek = DateTime.Now.DayOfWeek;
   if (dayOfWeek == DayOfWeek.Saturday || dayOfWeek == DayOfWeek.Sunda))
   {
      return $"Today's {dayOfWeek.ToString()}, take the day off"! 
   }

   //// Your code goes here...
}

It will start the job, but quit before actual work is done. Return a status describing that the job did not run, and why. That message will be available in the history tab.

If that does not fit your needs, you could possibly use IScheduledJobRepository to modify ScheduledJob.NextExecution, or even fiddle with the values in the database table tblScheduledItem directly. I would not recommend that, If you can get by with simply jumping out of the job on the weekends.

#210761
Edited, Dec 04, 2019 23:00
Vote:
 

Hi Ritu,

Is the scheduled job that you referring to is an inbuild schedule job or it is a custom schedule job?

  1. If it is custom then you can use the solution given above by Praful and Tom.
  2. But if it is an inbuild schedule job then you can go for two approaches-
    1. Disable the current schedule job execution and then create the new one with the extended logic.
    2. Or create a new schedule job that is only responsible for running the inbuild job so you can write the weekdays logic in that job. you can get more info for starting a schedule job programmatically  here
#210772
Dec 05, 2019 9:49
Vote:
 

Hi Ritu,

Building on what Ravindra said, if you want a solution which works for all jobs including the inbuilt ones you'll need to do something which controls the execution of the scheduled jobs. Rather than take the approach of having one job which is responsible for running the other jobs, I'd suggest having a job which periodically checks the scheduling of the other jobs and, if one is scheduled to run on the weekend, modify the next execution date to the following Monday like this:

[ScheduledPlugIn(DisplayName = "Skip Weekend Scheduled Job", IntervalType = ScheduledIntervalType.Minutes, IntervalLength = 15, DefaultEnabled = true)]
public class SkipWeekendScheduledJob : ScheduledJobBase
{
    private bool _stopSignaled;

    public SkipWeekendScheduledJob()
    {
        IsStoppable = true;
    }

    /// <summary>
    /// Called when a user clicks on Stop for a manually started job, or when ASP.NET shuts down.
    /// </summary>
    public override void Stop()
    {
        _stopSignaled = true;
    }

    /// <summary>
    /// Called when a scheduled job executes
    /// </summary>
    /// <returns>A status message to be stored in the database log and visible from admin mode</returns>
    public override string Execute()
    {
        OnStatusChanged(String.Format("Starting execution of {0}", this.GetType()));

        var jobRepo = ServiceLocator.Current.GetInstance<IScheduledJobRepository>();
        var sb = new StringBuilder();
        foreach (var job in jobRepo.List())
        {
            if (job.NextExecution.DayOfWeek.Equals(DayOfWeek.Saturday) || job.NextExecution.DayOfWeek.Equals(DayOfWeek.Sunday))
            {
                job.NextExecution = job.NextExecution.AddDays(job.NextExecution.DayOfWeek.Equals(DayOfWeek.Saturday) ? 2 : 1);
                jobRepo.Save(job);
                OnStatusChanged($"Updated {job.Name} to run on {job.NextExecution}");
                sb.AppendLine($"Updated {job.Name} to run on {job.NextExecution}");
            }

            //For long running jobs periodically check if stop is signaled and if so stop execution
            if (_stopSignaled)
            {
                return "Stop of job was called";
            }
        }

        var rtn = sb.ToString();
        if (rtn == string.Empty)
        {
            rtn = "Job completed successfully. No updates required.";
        }
        return rtn;
    }
}
#210776
Dec 05, 2019 11:57
Vote:
 

Thanks for the solutions everyone!

Paul,

On your solution, this job that will look at all the other jobs to skip on weekends, how will we be able to tell this job which jobs to skip and which jobs to let run on weekends? As far as I know there isn't a property on jobs to specify that. Your code above is pretty much doing it for all the jobs, isn't it?

Regards

Ritu

#210794
Dec 05, 2019 20:14
Vote:
 

Hi Ritu,

I already provided a link in my last comment for the code that you can refer but here the code you can refer-

var job = _scheduledJobRepository.Get(new Guid(MyJob.Guid));
job.ScheduleRunNow(_scheduledJobRepository);
#210796
Edited, Dec 05, 2019 20:23
Vote:
 

Hi Ritu,

if you want to switch off only certain jobs at weekends then you'd probably be best adding in an appsetting to the web.config with a comma separated list of the job names (or GUIDs if you know them). You could then check that list as you loop through the jobs in the Execute method like this:

public override string Execute()
{
    //Call OnStatusChanged to periodically notify progress of job for manually started jobs
    OnStatusChanged(String.Format("Starting execution of {0}", this.GetType()));

    var jobsToSkip = (ConfigurationManager.AppSettings["WeekdayOnlyJobs"] ?? string.Empty).Split(',');

    //Add implementation
    var jobRepo = ServiceLocator.Current.GetInstance<IScheduledJobRepository>();
    var sb = new StringBuilder();
    foreach (var job in jobRepo.List().Where(x => jobsToSkip.Contains(x.Name)))
    {
        if (job.NextExecution.DayOfWeek.Equals(DayOfWeek.Saturday) || job.NextExecution.DayOfWeek.Equals(DayOfWeek.Sunday))
        {
            job.NextExecution = job.NextExecution.AddDays(job.NextExecution.DayOfWeek.Equals(DayOfWeek.Saturday) ? 2 : 1);
            jobRepo.Save(job);
            OnStatusChanged($"Updated {job.Name} to run on {job.NextExecution}");
            sb.AppendLine($"Updated {job.Name} to run on {job.NextExecution}");
        }

        //For long running jobs periodically check if stop is signaled and if so stop execution
        if (_stopSignaled)
        {
            return "Stop of job was called";
        }
    }

    var rtn = sb.ToString();
    if (rtn == string.Empty)
    {
        rtn = "Job completed successfully. No updates required.";
    }
    return rtn;
}

If you're only wanting to switch off jobs you have source code access to though, the answer you've accepted is your best option. This scheduled job would only be required if you need to block the execution of inbuilt scheduled jobs or ones you've added via nuget etc.

#210813
Dec 06, 2019 11:08
Vote:
 

Hi Ritu,

I just added customization to allow editors to control the day(s) to skip the execution of job on specific day(s).

https://world.episerver.com/blogs/pjangid/dates/2019/12/skip-jobs-to-execute-on-specific-days-of-the-week/

Thanks to @Paul for inspiration.

#210829
Dec 07, 2019 9:49
Vote:
 

If you want this change to apply to every job, you could override SchedulerService which has some virtual methods. For example, GetNextScheduledJob() could just return null if you're on the "wrong" day.

#210962
Edited, Dec 13, 2019 14:05
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.