Interview Series: Queueable Apex

Interviewer: What is Queueable Apex?

Interviewee: It’s an extension of the Future Methods. It uses the Queueable interface which is an enhanced way of running your asynchronous Apex code compared to using future methods. The limitations which Future methods have, through Queueable Apex, we can overcome them.

Interviewer: How does Queueable Apex differ from Future methods?

Interviewee:

Queueable Apex is similar to future methods in that they’re both queued for execution, but they provide us these additional benefits.

  • When you queue a Queueable Apex, you get a job ID, that can be used to trace it easily, which is not possible in case of future methods.
  • You can use non-primitive datatypes in Queueable Apex, like objects and sObjects, which is not possible in case of future methods, because it supports only primitive data types as params.
  • You can chain jobs, by calling another starting a second job from a running job, which is not possible in case of future methods, because we can’t call another future method from a future context.

Interviewer: Can you write a sample Queueable Job?

Interviewee: Create a class, implement the Queueable interface, and override the execute method.

public class QueueableApexExample implements Queueable {
public void execute(QueueableContext context) {
//some process
}
}

Interviewer: What is QueueableContext?

Interviewee: It is an interface that is implemented internally by Apex, and contains the job ID. Once you queue the Queueable Job, the Job Id will be returned to you, by apex through QueueableContext’s getJobId() method.

Interviewer: How can I queue above Job(QueueableApexExample)?

Interviewee: Using System.enqueueJob Method.

ID jobID = System.enqueueJob(new QueueableApexExample());

Interviewer: How can I use this Job Id to trace the Job?

Interviewee: Just perform a SOQL query on AsyncApexJob by filtering on the job ID.

AsyncApexJob jobInfo = [SELECT Status,NumberOfErrors FROM AsyncApexJob WHERE Id=:jobID];

Interviewer: I have 200 records to be processed using Queueable Apex, How Can I divide the execution Context for every 100 records?

Interviewee: Similar to future jobs, queueable jobs don’t process batches, so you can’t divide the execution Context. It will process all 200 records, in a single execution Context.

Interviewer: Can I do callouts from a Queueable Job?

Interviewee: Yes, you have to implement the Database.AllowsCallouts interface to do callouts from Queueable Jobs.

Interviewer: How Chaining works in Queueable Apex?

Interviewee: Chaining allows us to customize the execution order of a set of jobs in a process.

let’s say there are N jobs, A, B, C and so on. We have a process in which A has to run first and gives output to B and then B runs and gives output to C and so on. So, instead of calling the individual Queueable Jobs explicitly, we can link the calls, logically within Queueable Jobs, as shown Below

public class A implements Queueable {
public void execute(QueueableContext context) {
// Chain this job to next job by submitting the next job
System.enqueueJob(new B());
}
}
public class B implements Queueable {
public void execute(QueueableContext context) {
// Chain this job to next job by submitting the next job
System.enqueueJob(new C());
}
}
public class C implements Queueable {
public void execute(QueueableContext context) {
// Chain this job to next job by submitting the next job
System.enqueueJob(new D());
}
}
and so on...

Interviewer: How many numbers of jobs, can be chained at a time?

Interviewee: You can add only one job from an executing job, which means that only one child job can exist for each parent job.

Since, no limit is enforced on the depth of chained jobs, you can chain one job to another. You can repeat this process with each new child job to link it to a new child job.

Interviewer: How many numbers of jobs, I can queue using System.enqueueJob() at a time?

Interviewee: You can add up to 50 jobs to the queue with System.enqueueJob in a single transaction in Synchronous apex. In asynchronous transactions, you can add only one job to the queue.

Interviewer: Can I chain a job that has implemented allowsCallouts from a Job that doesn’t have?

Interviewee: Yes, callouts are also allowed in chained queueable jobs.

Interviewer: Can I call Queueable from a batch?

Interviewee: Yes, But you’re limited to just one System.enqueueJob call per execute in the Database.Batchable class. Salesforce has imposed this limitation to prevent explosive execution.

Interviewer: If I have written more than one System.enqueueJob call, what will happen?

Interviewee: System will throw LimitException stating “Too many queueable jobs added to the queue: N”.

Interviewer: How can we handle this error, without using a try-catch?

Interviewee: We can check whether the current count of queuable jobs has exceeded the limit or not, if not, queue them.

Limits.getQueueableJobs() returns the currently queued jobs count.

Limits.getLimitQueueableJobs() returns the limit.

If(Limits.getQueueableJobs() < Limits.getLimitQueueableJobs()) {     //System.enqueueJob()}

Interviewer: I have a use case to call more than one Queueable Jobs from a Batch apex, how can I achieve it?

Interviewee: Since we can’t call more than one Queueable Job from each execution Context, We can go for scheduling the Queueable Jobs.

The approach is we need to first check how many queueable jobs are added in the queue in the current transaction by making use of Limits class. If the number has reached the limit, then call a schedulable class and enqueue the queueable class from the execute method of a schedulable class.

Interviewer: how to test a Queueable Job?

Interviewee: A queueable job is an asynchronous process. To ensure that this process runs within the test method, the job is submitted to the queue between the Test.startTest and Test.stopTest block.

Also, The ID of a queueable Apex job isn’t returned in test context — System.enqueueJob returns null in a running test.

Interviewer: how to test Chaining?

Interviewee: You can’t chain queueable jobs in an Apex test. So you have to write separate test cases for each chained queueable job. Also, while chaining the jobs, add a check of Test.isRunningTest() before calling the enqueueJob.

public class A implements Queueable {
public void execute(QueueableContext context) {
// Chain this job to next job by submitting the next job and it's context should not be a test case.
if(!Test.isRunningTest()){
System.enqueueJob(new B());
}
}
}

--

--