Recently I was looking for a way of scheduling a job to poll and API from salesforce. In the past we tried to use the Schedulable interface in Apex to create Schedulable jobs. But here is what we found.

Schedulable Interface

The schedulable interface works great for jobs that you want to schedule. But this type of job doesn’t work well for polling jobs. In our use case we wanted to poll an api as often as possible.

The problem occurs when the job runs into the next api call. If this happens then you could have 2 jobs running at the same time. When this happens we have seen it impact the performance of the salesforce org.

There were also issues with overlapping api calls where two jobs would end up processing the same records. These are issues that we were looking to avoid.

Queueable Interface

One of the unique attributes of the Queueable interface is that ability to chain jobs. This is easily done by calling the job again in the execute method using the System.enqueueJob method. This will ensure that jobs don’t overlap and only execute when the previous job has finished.

Example

public class PollApiExample implements Queueable {
  public void execute(QueueableContext context) {
    // Code for polling the API goes here

     // Code for chaining the next API Call
     // Test to make sure that Unit test are not running before chaining
     // the call.
     if(!Test.isRunningTest()) {
       System.enqueueJob(new PollApiExample());
     }
  }
}

In the example above next job isn’t queued until the current job finishes. We also make sure that the code is not running in the context of a Unit Test. We don’t want to chain another job during a Unit test run.

Another thing to consider is making sure that you build in some type of off switch for the chaining of jobs. You may want to turn off the chaining of the job using either a custom setting or a custom metadata record. Here is an example.

public class PollApiExample implements Queueable {
  public void execute(QueueableContext context) {
    // Code for polling the API goes here

     // Use custom setting to decide if we should call the next job.
     Chaining_Setting__c chainingSetting = 
                                Chaining_Setting__c.getOrgDefaults();
     // Code for chaining the next API Call
     // Test to make sure that Unit test are not running before chaining
     // the call.
     if(!Test.isRunningTest() && chainingSetting.ChainJobOn__c) {
       System.enqueueJob(new PollApiExample());
     }
  }
}

In this example we have a custom setting defined as Chaining_Setting__c. This object has a field called ChainJobOn__c. If ChainJobOn__c is true then we will queue the job to run again. Otherwise the job in not queued and the job chain stops here.

Conclusion

The Queueable interface is a good mechanism to use in salesforce where you have the need to chain jobs together like you would need to in order to poll an api. This technique prevents jobs from overlapping each other which would happen if you scheduled the jobs very close to one another using the Schedulable interface.

Important Links

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_scheduler.htm – Scheduler Interface

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_queueing_jobs.htm – Queueable Interface

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_custom_settings.htm – Custom Setting