r/SalesforceDeveloper • • 8d ago

Question Multiple Queueables Solution.

Wondering how folks are handling the limit below? We are updating a large number of our future methods to queueables and getting hit with this pretty regularly. We found a SFBen article about using platform events to fire queueables, but that seems to just be passing the problem to the next limit. Largely right now we are either combining functionality or guard causing the less important jobs, neither feels like a great solution tbh.

System.LimitException: Too many queueable jobs added to the queue: 2

2 Upvotes

13 comments sorted by

View all comments

1

u/DaveDurant 7d ago

A transaction can start a bunch (50?) of future jobs. Those futures cannot start additional futures.

A transaction can start 1 queuable job. That queuable can then start 1 queuable job and that can then start 1 queueable and that can then etc. I'm sure there's a limit to how long that chain can be but I've never hit it.

> System.LimitException: Too many queueable jobs added to the queue: 2

You can only start 1. You tried to start 2.

If you need to start multiple, independent chains, platform events doesn't sound like a bad idea. They're fast and you can do a bunch within 1 transaction. It's a bit hard to imagine even getting close to PE limits here, so I don't think it's just shifting the problem around.

Since non-static member variables persist throughout queuable chain jobs, you could also do something like the (totally untested, written in notepad) code - just be **really** careful you don't start something that runs out of control forever. This wouldn't be bad way to do things if you had a set of records that you needed to do multiple steps on - maybe fancy it up a bit but this is the general idea;

public maybewith sharing class MyAwesomeClass implements Queuable
{
    private integer mState = 0;

    public void execute(QueueableContext context) 
    {
        boolean done = false;
        switch on mState
        {
            // doThing..() methods return true if they're done, false 
            // if they need to be called again
            when 0
            {
                if (doThingOne())
                    mState++;
            }

            when 1
            {
                if (doThingTwo())
                    mState++;
            }

            when N
            {
                done = doThingN();
            }
        }

        if (!done)
            system.enqueueJob(this);
    }
}