Schedule Recurring Apex Every X Minutes

Author: Bruce Tollefson Published: January 27, 2022; Modified: May 9, 2022
bot

Using the Schedulable interface gives you the ability to schedule a batch, class, queueable, etc. The interface is called with the System.schedule() method taking in 3 parameters a String for the job name, a String for a cron expression, and an Object of a schedulable class. This provides the ability for flexibility, to schedule through a class. Potentially chaining a schedulable to run and at the end schedule it to run again at a later time.

Salesforce provides a configurable way to schedule an Apex batch, class, queueable, etc. by going to Setup –> Apex Classes –> ‘Schedule Apex’

After clicking ‘Schedule Apex’ you are prompted to create a job name, pick the schedulable apex class, and determine the frequency.

Using the configuration you are only able to schedule the apex class once and if you try to schedule for a different time you will see an error: This Apex class is already scheduled for execution.

What if you want to schedule a job for every 5 minutes? Every 2? The only way you are able to is through the System.schedule() method. You can use execute anonymous in the developer console to create a cron expression for each interval. Or use the following apex:

public class DynamicJobScheduler { private class DynamicJobSchedulerException extends Exception {} //anything above 30 will only create 1 per hour and anything above 60 minutes will not create a schedulable job public static void scheduleRecurringJob(String jobName, Integer minutes, String batchName){ Type batchType = Type.forName(batchName); Object batchObj = batchType.newInstance(); if(!(batchObj instanceof Schedulable)) throw new DynamicJobSchedulerException('The batch must implement the Schedulable interface https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_scheduler.htm'); Schedulable SchedulableObj = (Schedulable)batchObj; Datetime sysTime = System.now(); Integer numberOfJobs = 60/minutes; if(numberOfJobs <= 0)throw new DynamicJobSchedulerException('Anything above 60 minutes will not create a scheduleable job'); for(Integer i = 0; i < numberOfJobs; i++){ Integer addMinutes = i*minutes; Datetime sysTimeWithMinutes = System.now().addMinutes(addMinutes); String cronExpression = '' + 0 + ' ' + sysTimeWithMinutes.minute() +' * * * ?'; system.debug(cronExpression); System.schedule(jobName+addMinutes, cronExpression, SchedulableObj);//make dynamic } } }

The above apex is a class that could either be deployed and executed through execute anonymous or simply used in execute anonymous. The class will schedule a set of jobs for x number of minutes in an hour and dynamically create the apex class that implements the schedulable interface.

Here is the GitHub repo.

Considerations

There are a couple of considerations to make. The first one is the code above uses the Type.newInstance() method. This method only works when you are trying to create an APEX instance with an empty constructor. If the class does not have an empty constructor that can be used the class can be instantiated beforehand you can use the following:

public class DynamicJobScheduler { private class DynamicJobSchedulerException extends Exception {} //anything above 30 will only create 1 per hour and anything above 60 minutes will not create a schedulable job public static void scheduleRecurringJob(String jobName, Integer minutes, Schedulable schedulabledApex){ Datetime sysTime = System.now(); Integer numberOfJobs = 60/minutes; if(numberOfJobs <= 0)throw new DynamicJobSchedulerException('Anything above 60 minutes will not create a scheduleable job'); for(Integer i = 0; i < numberOfJobs; i++){ Integer addMinutes = i*minutes; Datetime sysTimeWithMinutes = System.now().addMinutes(addMinutes); String cronExpression = '' + 0 + ' ' + sysTimeWithMinutes.minute() +' * * * ?'; system.debug(cronExpression); System.schedule(jobName+addMinutes, cronExpression, schedulabledApex); } } }

Which can be called as:

DynamicJobScheduler.scheduleRecurringJob('Testing Dynamic Schedulable Tester', 15, new SchedulableTest());

The second consideration is to be careful of the following exception: System.AsyncException: You have exceeded the maximum number (100) of Apex scheduled jobs. This error will occur when you have more than 100 scheduled future jobs.

2 comments on “Schedule Recurring Apex Every X Minutes”

  • Liron says:

    Thanks.
    It is working. Just has 2 potential issues:
    1.If having many processes and each should run every few minutes then might get very fast to the max schedules apex (100)
    2.Have to use empty constructor in the Scheduler class. Unfortunately SF doesn’t support constructor with parameters when using newInstance() method. Can overcome this by using your own interface but I guess this can be in other article.

    +In recent project I used dedicated tool for managing the jobs and recently publish it: <a href="https://lc169.blogspot.com/2022/02/tool-for-manage-and-build-and-run.html" rel="nofollow ugc">https://lc169.blogspot.com/2022/02/tool-for-manage-and-build-and-run.html</a>

  • Leave a Reply

    Your email address will not be published. Required fields are marked *