0

Edit: Sorry for the confusion! I’m trying to use this generic framework I mentioned below the error message I’m getting from my code which is calling a standard queueable class.

So, my question: I tried to use this new generic framework I could not able to make it work meaning it’s not calling the queueable execute method.

if you have to use this generic framework how would you use? there is no example or test class so I could not figured out.

End edit:

I'm working on an existing codebase and trying to make the queueable more generic and current code is tightly coupled and getting the error of Too many queueable jobs added and I found this particular framework that talks about how can this generic framework helps make it loosely coupled but I'm not really sure how to implement and here is what I have done so far.

Error:

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

github: https://github.com/aykutparlak/genericasync

website: https://www.apexhours.com/generic-approach-to-salesforce-queueable/

AsyncJob

//added new overload method to AsyncJob class:

public AsyncJob(String jobName, String jobClass, String jobMethod, List<Account> accounts) {
    this.jobName = jobName;
    this.jobClass = jobClass;
    this.jobMethod = jobMethod;
    this.accounts = accounts; 
}

AsyncJobService:

//added new method:

  public static void addJobNew(String jobName, String jobClass, String jobMethod, List<Accounts> accounts) {
            AsyncJob job = new AsyncJob(jobName, jobClass, jobMethod, accounts);
            addJob(job);
  }

GenericCallable

// here you can implement the new class/method

try {
       if (job.jobClass == 'System' && job.jobMethod == 'debug') {
           System.debug(job);
       } else if (job.jobClass == 'CLASS_NAME' && job.jobMethod == 'Execute') {
           AccountsQueuebleJob accQ = new AccountsQueuebleJob(job.accounts);
           System.enqueueJob(accQ);
       } else {
           throw new GenericCallableException('Method not implemented');
       }
          job.jobStatus = 'OK';
       } catch (Exception e) {
          job.jobStatus = 'ERROR';
          job.jobError = e.getMessage();

}

//AccountsQueuebleJob

public class AccountsQueuebleJob implements Queueable, Database.AllowsCallouts {
    private List<AsyncJob> jobs;
    private Integer currentJobNumber;

    public AccountsQueuebleJob(List<AsyncJob> jobs, Integer currentJobNumber) {
        this.jobs = jobs;
        this.currentJobNumber = currentJobNumber;
    }

    public GenericQueueable(List<AsyncJob> jobs) {
        this.jobs = jobs;
        this.currentJobNumber = 0;
    }

    public void execute(QueueableContext context) {
        GenericCallable gc = new GenericCallable();
        gc.call('CLASS_NAME', new Map<String, Object>{ 'jobs' => this.jobs, 'currentJobNumber' => this.currentJobNumber });
    }
}

Problem: It does not run the execute method of queueable class.

5
  • You've put together several things here that don't necessarily go together, before we even look at the code. You're not receiving that limit exception because your Queueables are not using a generic framework. It's unclear to me what loose coupling (between what and what?) has to do with the rest of the problem. Your limits issue could simply be poorly-constructed logic enqueuing the Queueable class, or trigger recursion.
    – David Reed
    Commented Dec 6, 2022 at 1:07
  • 1
    I don't like the linked pattern much, myself - it's a lot of code that doesn't actually get you very much utility. If you really need to build a framework for managing queued work, the kind of pattern developed by Dan Appleman in Advanced Apex Programming is in my opinion much better. But again, I'm not convinced you need that at all.
    – David Reed
    Commented Dec 6, 2022 at 1:11
  • I have not read the above book, but without sharing the content, how would you describe the pattern he wrote? I have written a pattern/engine which I have called a Serial Processing Engine and is not hard tied to the trigger framework, very loosely coupled, you could just about say it is not coupled at all. Salesforce has called these Queueables, but they are not queued. but they definitely work better than Schedulables and Batchables. Commented Dec 6, 2022 at 2:20
  • ...and better than future methods too. Commented Dec 6, 2022 at 6:52
  • I'm with David here - the Appleman pattern allows for retry of failed jobs which is so handy
    – cropredy
    Commented Dec 7, 2022 at 2:03

1 Answer 1

0

Your problem is not the queueable framework. your problem is how and when that code/framework is instantiated.

the error is telling you that you are adding a second queueable within the same transaction.

for example you cannot enqueue within a for loop. so maybe your using within an insert/update trigger and the trigger is does not have a good trigger handler.

At this point I am guessing because you have not provided everything in the code but.

So trace it back and debug it.

If you instantiate it multiple times across triggers, the trigger point is where you need to focus not the Queueable Framework.

To your comment about it not running the execute method: "Problem: It does not run the execute method of queueable class."

Queuable will run when salesforce is good a ready for it to run, I have seen them take 5 minutes to run.

so neither will run if they are being enqueued twice and the code is failing, most likely there will be nothing in the queue.

check your Apex jobs: "yourdomain.lightning.force.com/lightning/setup/AsyncApexJobs/home"

personally I do not use Salesforce's standard documented framework, I build out another model that means I can have different queueable names, so that I can see them firing in apex jobs, without debug turned on.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .