Interview Series: Apex Scheduler

--

Interviewer: What is an Apex Scheduler?

Interviewee: Apex Scheduler is an ability to invoke an Apex class to run at specific times.

Interviewer: What could be the use cases for this?

Interviewee: There could be many use cases

For example:

  1. Sending Periodic notifications to users.
  2. NewsLetters on the 15th of every month.
  3. Tasks related to real-time updates.

Interviewer: Ok. So, what are the prerequisites for the apex scheduler?

Interviewee: The apex class needs to implement the Salesforce-provided interface Schedulable. and override it’s execute() method.

Interviewer: Can you write the basic Apex structure of a class that can be scheduled?

Interviewee:

global class SampleSchedulerClass implements Schedulable {
global void execute(SchedulableContext SC) {
//Some code that would be called
}
}

Interviewer: What is SchedulableContext?

Interviewee: It contains the scheduled job ID using the getTriggerID() method. This interface is implemented internally by Apex.

Interviewer: And what would be the use of that Job ID?

Interviewee: with that ID, we can track the Progress of a Scheduled Job through a query on CronTrigger. The ID is of type CronTrigger.

Moreover, we can go to Setup-> Scheduled Jobs too, for monitoring.

Interviewer: So, How can I schedule the apex class?

Interviewee: Once you are done with the implementation. You can schedule it either through the

Developer console using system.schedule method.

SampleSchedulerClass obj = new SampleSchedulerClass();
String CRON_EXP = ’20 30 8 10 2 ?’;
String jobID = system.schedule(‘Sample Scheduler Job’, CRON_EXP, obj);

OR

UI : Setup -> Develop -> Classes

You will see a “Schedule Apex” button. You can set up the timing from there.

Interviewer: As you mentioned that the jobID can be used to query the progress, how can we track it?

Interviewee: We can simply fire a query to get information about current job

CronTrigger ct = [SELECT CronExpression,CronJobDetailId,PreviousFireTime,TimesTriggered, NextFireTime,State,StartTime,EndTime FROM CronTrigger WHERE Id =: jobID];

Interviewer: What is this CronJobDetailId?

Interviewee: CronJobDetail is the parent CronTrigger that saves a job’s information like Name, JobType, etc.

JobType value is always 7 for Scheduled Apex.

we can get these details too using the same CronTrigger query.

CronTrigger job = [SELECT Id, CronJobDetail.Id, CronJobDetail.Name, CronJobDetail.JobType FROM CronTrigger where Id =: jobId];

Or

Can query on CronJobDetail with CronJobDetailId.

CronJobDetail ctd = [SELECT Id, Name, JobType 
FROM CronJobDetail WHERE Id = :CronJobDetailId];

Interviewer: what is CRON_EXP?

Interviewee: It is called CRON EXPRESSION which is used to define the scheduling time. it has 6 to 7 inputs,

Seconds, Minutes, Hours, Day_of_month, Month, Day_of_week, optional_year

it uses some special characters too

? — No Value
* — All Values
? — Specifies no specific value
/-Specifies increments. The number before the slash specifies when the intervals will begin, and the number after the slash is the interval amount.
#-Specifies the nth day of the month, in the format weekday#day_of_month
L-Specifies the end of a range (last)
W-Specifies the nearest weekday(Monday-Friday) of the given day

Interviewer: why is the purpose of special characters?

Interviewee: The purpose of special characters is to define a range or interval. They are like wildcard characters in database queries.

For example, If I want to run a job at 12 midnight on the 1st of every month in 2021,

my CRON_EXP would be

“0 0 0 1 * 2021”

where * = all values possible for a month i.e. 1–12

Interviewer: Ok... So write CRON_EXP for scheduling a job at

  1. 5:15 PM on the third Friday of every month.
  2. at the last Friday of every month at 6:00 PM.
  3. every 30 minutes

Interviewee:

  1. “0 15 5 ? * 6#3” (? for not specifying a day, because it’s the nth day)
  2. “0 0 18 ? * 6L” (? for not specifying a day, because it’s last day)
  3. “0 30 * * * *”

Interviewer: So let's say, I have scheduled an apex class to run at 3 pm today, and at 3 pm, some batches are already running. How will your apex class code run at 3 pm?

Interviewee: It will get scheduled on time because Salesforce schedules the class for execution at the specified time, But the Actual execution may be delayed based on service availability. So, it will run once everything is done.

Interviewer: Cool, let’s say, I have scheduled an apex class to run at 3 pm today, and at 3:15 pm, downtime occurred. What will happen now?

Interviewee:

There could be 2 cases,

  1. Before starting the job, downtime occurred, in this case, Apex jobs will be scheduled to run after the service comes back up, when system resources become available.
  2. If a scheduled Apex job was running when downtime occurred, the job is rolled back and scheduled again after the service comes back up.

Interviewer: What async processes, I can schedule?

Interviewee: We can schedule

  1. Batch Apex (can call a batch from Scheduled Apex)
  2. Future Method (can call future from Scheduled Apex)
  3. queueable apex (can call queueable form Scheduled Apex)

Interviewer: Which of the above can cause an issue?

Interviewee: Calling the Future methods from scheduled apex can cause some issue:

  1. the future won’t guarantee it’s execution on time, so tracking is not possible. Also, we lose transaction control because the scheduled apex gets over as soon as it fires the future method call.
  2. there is a limit to the number of future calls based on your number of licenses

Interviewer: Maximum, How many jobs can be scheduled at any point in time?

Interviewee: You can only have 100 scheduled Apex jobs at one time.

Either we can verify the count by viewing the Scheduled Jobs page OR

we can simply query with CronJobDetail.JobType as 7 (scheduled Apex) on CronTrigger

SELECT COUNT() FROM CronTrigger WHERE CronJobDetail.JobType = ‘7’

Interviewer: How can you stop the execution of a job that has already been scheduled?

Interviewee: To stop the execution of a job that has been scheduled, use the System.abortJob method with the ID returned by the getTriggerID method.

Interviewer: Can we write a Unit test case for a scheduled Apex?

Interviewee: Yes we can.

Use the Test methods startTest and stopTest around the System.schedule method to ensure it finishes before continuing your test.

All asynchronous calls made after the startTest method are collected by the system.

When stopTest is executed, all asynchronous processes are run synchronously.

If you don’t include the System.schedule method within the startTest and stopTest methods, the scheduled job executes at the end of your test method

global class TestScheduledApexFromTestMethod implements Schedulable {// This test runs a scheduled job at midnight Sept. 3rd. 2022public static String CRON_EXP = '0 0 0 3 9 ? 2022';

global void execute(SchedulableContext ctx) {

}
}
/*****************************************************/
@istest
class TestClass {
static testmethod void test() {
Test.startTest();
String jobId = System.schedule('testBasicScheduledApex',
TestScheduledApexFromTestMethod.CRON_EXP,
new TestScheduledApexFromTestMethod());
// Get the information from the CronTrigger API object
CronTrigger ct = [SELECT Id, CronExpression, TimesTriggered,
NextFireTime
FROM CronTrigger WHERE id = :jobId];
// Verify the expressions are the same
System.assertEquals(TestScheduledApexFromTestMethod.CRON_EXP,
ct.CronExpression);
Test.stopTest();}
}

Interviewer: Can you tell Best Practices to be followed while using Scheduled Apex?

Interviewee:

  1. Synchronous Web service callouts are not supported from scheduled Apex. To be able to make callouts, make an asynchronous callout.
  2. While scheduling a job from the trigger, we must be able to guarantee that the trigger won’t add more scheduled classes than the limit.

--

--