7

I have the following pseudo-code, and what I am attempting to do is chain queues that require call outs, I have read around and saw that you can't create another queue after a call out. I see the work around is you call a future that queues up the next job. Is this the only way to do this? Does anyone know any other patterns? My comments below represent roughly my desired design.

Known limitation, idea is opened https://success.salesforce.com/ideaView?id=08730000000Dl7VAAS

Will accept Can we callout and chain a Queueable class? as an answer unless someone else has some ideas

public with sharing class OnBoardingFacade implements Queueable, Database.AllowCallOuts
{

// -------- Methods --------
public void execute(QueueableContext context) 
{   
    if(first)
    {
        System.enqueueJob(new OnBoardingFacade());
        System.debug('THE CONTEXT 1' + context);
        //Callout 1, Sucessful go to second
    }
    else if(second)
    {
        System.enqueueJob(new OnBoardingFacade());
        System.debug('THE CONTEXT 2' + context);
        //Callout 2, Succesful go to third

    }
    else if(third)
    {
        System.enqueueJob(new OnBoardingFacade());
        System.debug('THE CONTEXT 3' + context);
        //Callout 3, Succesful finish.  
    }           
}
}
  • 1
    You just have to perform all dml operations after the callout. The enqueueJob method performs dml. I would think if you just move enqueueJob to the end it should work, but I haven't tried it. – Adrian Larson Aug 2 '16 at 20:02
  • After my first call out I require updates to my object in order to do my second call out in order to build the json for the next call out, I don't believe there is a way to get around an @future – EricSSH Aug 2 '16 at 20:09
  • 2
    You can either use @future or you can use Batchable, but you can't use another Queueable directly. My question also asked the same thing. Until we get word from salesforce that they'll allow it, we're stuck with what we have. – sfdcfox Aug 2 '16 at 20:11
  • Should we close as duplicate? – Adrian Larson Aug 2 '16 at 20:19
  • 2
    @AdrianLarson I consider them strongly related, but I think mine is more geared towards "how do we get it to work" (we don't), versus "can I do something else" (which we can). I look forward to other alternatives as well. – sfdcfox Aug 2 '16 at 20:23
8

The other alternative is to not use Queueable for that purpose. I actually wrote a very fancy Batchable class that did something like that. One interesting design pattern is to make a batch action buffer. It basically looks like this:

global class ChainBatch implements Database.Batchable<BatchAction>, Database.AllowsCallouts, Database.Stateful, Iterable<BatchAction>, Iterator<BatchAction> {
    global interface BatchAction {
        void performAction(ChainBatch state);
    }
    global Iterator<BatchAction> iterator() {
        return this;
    }
    global Boolean hasNext() {
        return !buffer.isEmpty();
    }
    global BatchAction next() {
        return buffer.remove(0);
    }
    BatchAction[] buffer = new BatchAction[0];
    global class Step1 implements BatchAction {
        global void performAction(ChainBatch state) {
            // Do something here
        }
    }
    // More classes here
    global Iterable<BatchAction> start(Database.BatchableContext context) {
        buffer.add(new Step1());
        buffer.add(new Step2());
        buffer.add(new Step3());
        return this;
    }
    global void execute(Database.BatchableContext context, BatchAction[] scope) {
        scope[0].performAction(this);
    }
    global void finish(Database.BatchableContext context) {
    }
}

Make sure this class is called with a scope size of 1, of course. This is entirely more complicated than some other patterns, but does allow the chaining to continue even in the face of blown governor limits.

  • I like this design and will consider doing something like this, but then I also think if one day they allow chaining from queueables it would be easier to migrate from the future calls to enqueue them. – EricSSH Aug 2 '16 at 20:30
  • I don't think I've ever seen such a long implements list! I definitely like consolidating like that whenever possible. – Adrian Larson Aug 2 '16 at 20:45

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.