0

Title of the question is mis-leading. Since yes, a queueable method can access a static variable of a class. But i have an existing old implementation, and i am trying to refactor and clean it up. There is a line in code that i dont think makes any difference, but wanted to get other people's opinion, since my experience level is limited

I have a trigger on case-

trigger caseTrigger on Case (before insert,before update, after insert, after update){
    if (Trigger.isBefore) {
            if (Trigger.isInsert)  {/*do something*/} 
            if (Trigger.isUpdate) {/*do something*/}           }
        }

        if(Trigger.isAfter && !CaseTriggerHandler.afterCallsExecuted){
            if(Trigger.isUpdate){
                CaseTriggerHandler.afterUpdate(trigger.new, trigger.old);
            }
            if (trigger.isInsert) {
                CaseTriggerHandler.afterInsert(trigger.new);
            }
            CaseTriggerHandler.afterCallsExecuted = true; 
        }
}

From what i gather, the boolean variable CaseTriggerHandler.afterCallsExecuted is used to make sure afterInsert does not get execute more than once in case of recursion. All good here. My concern is in handler there is a place where they are setting it to true as well. And it's in a queueable method.

This is the code for trigger handler class (removed redundant stuff for sake of brevity)

public without sharing class CaseTriggerHandler{
    public static boolean afterCallsExecuted = false;

    public static void afterInsert(list<Case> newList) {
        CaseTriggerHandler.sendCaseToSalesforceOrg(newList, null);
    }

    public static void afterUpdate(list<Case> newList, list<Case> oldList) {
        CaseTriggerHandler.sendCaseToSalesforceOrg(newList, oldList);
    }

    private static void sendCaseToSalesforceOrg(list<Case> newList, list<Case> oldList){
        List<Id> caseIdsToSend = new List<Id>();
        //bunch of stuff to basically populate this List<Id> from newList
        //lets assume after this List<Id> has some list of IDs
        ID jobID = System.enqueueJob(new JitterbitCalloutQueuebleJob(caseIds));
    }

    public class JitterbitCalloutQueuebleJob implements Queueable, Database.AllowsCallouts{
        public List<Id> caseIds{get; set;}
        public JitterbitCalloutQueuebleJob(List<Id> caseIds){
          this.caseIds = caseIds;
        }
        public void execute(QueueableContext context) {
          CaseTriggerHandler.afterCallsExecuted = true; //does this here makes any sense?
          CaseTriggerHandler.jitterbitApiCallUtil(caseIds);
        }
    }

    public static String jitterbitApiCallUtil(List<Id> caseIds){
        //do all the work of transferring cases 
    }
}

So both after insert and after update call a method to transfer cases using jitterbit. This code is skeleton version of that, so i could show series of method calls.

JitterbitCalloutQueuebleJob.execute method sets that boolean variable to true.

From what i understand, this job will be queued, and case trigger is done. Later when the queued job is executed by server, sure it can set that handler class's boolean variable to true, but its pointless. Case trigger isn't even running right now. So goal to prevent recursion for after trigger isn't being addressed by this queueable job.

Just want o get other people's opinion on it. Want to make sure i am correct before i go about deleting that line.

3
  • 1
    Does jitterbitApiCallUtil() end up updating any Case records in Salesforce after the callout returns? If so, that'd be why the execute() method is setting that static var (otherwise you'd get into an endless callout loop).
    – Derek F
    Oct 18, 2020 at 1:02
  • @DerekF Oh my lanta ..... you are correct. Its updating cases. In those 2000 lines of code i missed that. Thank you so much. This answers it. If you post it as an answer, i could mark it as correct answer Oct 18, 2020 at 3:12
  • Just an FYI: the use of a simple static Boolean to avoid recursion is certainly not "all good". Take a look at this Q&A.
    – Phil W
    Oct 18, 2020 at 21:23

1 Answer 1

1

Hard to say for certain without seeing all of the jitterbitApiCallUtil() method, but based on the comments, it does appear that this method is updating Case records after the callout is completed.

While Queueable preserves the object state of non-primitive typed member variables of the instance passed to System.enqueueJob(), the execute() method is still running in a new transaction. Static variables are reset, and that includes CaseTriggerHandler.afterCallsExecuted.

Re-setting that static variable in the execute() method prevents any updates to Cases from making another round of callouts.

Without that static variable being set, an update to any of the Cases whose Ids are passed into the JitterbitCalloutQueuebleJob constructor would cause you to set up an infinite chain of queuables + callouts.

You must log in to answer this question.

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