14

As per the documentation we can only call 1 future from Queueable context.

enter image description here

But in below code I am able to call multiple future methods from same queueable class and no error is being thrown.

public with sharing class QueuableTest implements System.Queueable {
    public void execute(QueueableContext qc) {
        QueuableTest.future1();
        QueuableTest.future2();
        // Created future methods in another class
        // AccountTriggerHelper.future2();
        // AccountTriggerHelper.future3();
        System.debug('I am in queueable class');
    }
    @future
    public static void future1() {
        System.debug('Future 1');
    }
    @future
    public static void future2() {
        System.debug('future 2');
    }
}

On enqueuing above class I get 3 debug logs 2 for "future handler" and 1 for "Queueable handler". Shouldn't it error out, because I am calling 2 future methods - but only 1 is allowed?

enter image description here

11
  • 1
    I am also able to call more than 1 future method from queueable apex. Interesting
    – Amit Singh
    May 31, 2022 at 9:43
  • 2
    Its got be either a bug in apex or misleading documentation. I did some testing and queueable apex seems to support up to 50 future methods calls per queueable apex invocation, which seems to be the same limit as # of future methods that can be called from a synchronous apex transaction. I try to run this from Salesforce support and try to get some answers.
    – arut
    May 31, 2022 at 12:13
  • 1
    I have. Hopefully there should be some update from them soon.
    – arut
    Jun 3, 2022 at 7:00
  • 1
    I have this on my radar and will let you know as I have more details. Thx
    – Swetha
    Jun 3, 2022 at 11:24
  • 2
    @Elijah Can you share the support case number please. Generally, this is a bug. Developers shouldn't rely on it. There is the potential to create async jobs that branch out rapidly and consume the entire async apex limit. Jun 3, 2022 at 17:49

1 Answer 1

0

The reported scenario has been identified as an issue with how limits are enforced for future recursion. Our product development team(all thanks to @DanielBallinger ) has filed a bug #W-11247010 for this behaviour.

According to the filed bug, Limits.getLimitFutureCalls() is incorrectly returning 50 when called in a future method. Ideally, it should return 0 when called from a future method.

It indicates that a future method could be invoked. However, attempting to do so results in an System.AsyncException with the message:

Future method cannot be called from a future or batch method

The exception is expected here, but the Limits class is returning a misleading value.

In contrast, the Limits.getLimitQueueableJobs() method returns the expected value of 1.

One plus side of this is that the future method itself can't be used to fan out the volume of async jobs. Only the Queueable to Future step permits that.

The below example future method that shows Limits.getLimitFutureCalls() returns 50 when System.isFuture() is true. The value should actually be 0 (zero) in this case.

// FutureTest.future1('base', 0);

public class FutureTest {
    @future
    public static void future1(string baseName, integer depth) {
        System.debug('Future 1 [' + baseName + '] Depth: ' + depth);
        System.debug('FutureCalls: ' + Limits.getFutureCalls() + '/' + Limits.getLimitFutureCalls() );
        System.debug('System.isFuture: ' + System.isFuture() );
        
        if(Limits.getLimitFutureCalls() > 0 && Limits.getFutureCalls() < Limits.getLimitFutureCalls()) {
            // This should be impossible from a Future method!
            // Throws Future method cannot be called from a future or batch method:...
            FutureTest.future1(baseName + ' > Future!1_' + depth, depth + 1);
        }
    }
}

We have also filed a bug #W-11261710 that Queueable execution can start 50 child @Future jobs.

Known issue link: trailblazer.salesforce.com/issues_view?id=a1p4V00000214kJQAQ

5
  • Thanks @DanielBallinger & @Swetha for following-up. Sounds like the bug is not just related to Limits.getLimitFutureCalls() because if the platform were to depend on this value alone, then future recursion should also happen (which fortunately doesn't happen).
    – arut
    Jun 7, 2022 at 8:07
  • 1
    @arut We have also filed a bug #W-11261710 for investigating the present functionality that we can call more than one future method from a queueable context. This also includes having the documentation to reflect the current situation.
    – Swetha
    Jun 8, 2022 at 5:35
  • This bug tracking seems more relevant to this question. I guess these bug # are internal to SF product team and not one of those known issue identifiers.
    – arut
    Jun 8, 2022 at 6:01
  • 1
    That's correct! These are internal to the salesforce. I'll check if I can get a public-facing known issue created. Until then, can follow up for status using a support case with the bug reference number.
    – Swetha
    Jun 8, 2022 at 6:07
  • Appreciate the quick response
    – arut
    Jun 8, 2022 at 6:24

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.