22

I'll jump right into some code:

public class ChainQueue implements Queueable, Database.AllowsCallouts {
    public void execute(QueueableContext context) {
        if(QueueUtil.hasNext()) {
            MyWSUtil.makeCallout(QueueUtil.next());
        }
        if(QueueUtil.hasNext()) {
            System.enqueueJob(this);
        }
    }
}

Assuming MyWSUtil.makeCallout is a public static function that performs a callout from a queue item (being a custom object that queues up pending integrations), and QueueUtil has static methods that handle getting pending queue items and/or determining if there are more records to process, this code will fail.

If no callout happens, the chain ends and everything is okay. If a callout occurs, and we then attempt to chain, we receive an error about the "maximum callout depth has been reached." Implementing Database.AllowsCallouts appears to prevent System.enqueueJob from being able to chain, and not including Database.AllowsCallouts causes a "Callout not allowed from this future method" when making the callout.

Is there some combination of attributes that will allow us to chain and queue? Using callouts from queueable would move us off a very unstable batch process that has to simulate parallelism by switching between a number of integrations (much like a multitasking OS does), rather than intuitively spawning off batches (which are limited to 5, and we have up to 14 integration threads that need to run, and more are expected later).

If this isn't possible today, are the plans to support this in the future? Any documentation or advice would be helpful.

  • Have you read the following article developer.salesforce.com/blogs/engineering/2014/10/…. Some very good post on the bottom of the page. So you can call or chain but not both in same time. – Cloud Ninja Mar 24 '15 at 22:11
  • @brovasi I actually linked that blog post in the other question. I guess I just failed to read the comments. It would be nice to get input from someone if that will ever be allowed, or if the system is just going to keep forcing us to find more devious ways to run our integrations the way we need to. – sfdcfox Mar 24 '15 at 22:19
  • You might already know this (hopefully useful for people coming in via Google) but there is an idea for this: success.salesforce.com/ideaView?id=08730000000Dl7VAAS In that idea, it seems like SF regard this as a bug that was due to be fixed in Summer 15, but might now be Winter 16. goes away to write horrible batch-based workaround – Aidan Sep 9 '15 at 10:03
  • This bug still reproduced on Winter 16 org... Look's like Salesforce is focused on new features and fixing of old issues is not in the pipeline... :( – steals Nov 20 '15 at 14:43
  • Hitting this with a chained Queueable and getContentAsPdf being treated as a callout critical update turned on. Frustrating. – Keith C Nov 20 '15 at 19:34
6

Spring '17 provides:

Make Web Service Callouts from Chained Queueable Jobs

Apex now allows web service callouts from chained queueable jobs. Previously, a queueable job could make a web service callout, but additional chained jobs that made callouts would throw exceptions.

See Also:

Idea Exchange: Allow Callouts from Chained Queueable Apex Jobs

10

As Dan Appleman notes in the latest edition of Advanced Apex, a Queueable can call a Future method, and a Future method can enqueue a Queueable job. This works in Spring 16, and will allow chaining of an unlimited number of Queueable jobs, regardless of whether they do a callout or not.

public without sharing class thisQueueable 
    implements Queueable, Database.AllowsCallouts
{
    //...

    @Future(callout=true)
    public static void tryToQueue()
    {
        System.enqueueJob(new thisQueueable());
    }


}

This should allow you to chain Queueables indefinitely.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.