0

I am having some issues with making a callout in my for loop. I have a batch class that calls my queueable class which then loops through and sends a single parameter to the endpoint. What is happening is that I either get a Read Time Out or Exceeding Max Time Allotted For Callout (120000). I believe the connection is being kept open and it is not closing the connection on each call out. Any ideas on how I can handle this? Right now I'm limiting the batch to 1 and it is working however it is not bulkifying any of my inserts.

HttpRequest docRequest = new HttpRequest();
            docRequest.setMethod('GET');
            docRequest.setHeader('Content-Type', 'application/json');
            docRequest.setHeader('Authorization','Bearer '+accessToken);
            docRequest.setHeader('Connection','Close');
            docRequest.setTimeout(120000);
            System.debug('$$$$ after doc request');
            Http docHttp = new Http();

            for(String cisItem :cisIdPaaListMap.keySet())
            {
                System.debug('cisItem '+cisItem);
                cisId = cisItem;
                System.debug('&&& inside else ');
                System.debug('2 Queued jobs '+Limits.getQueueableJobs());
                docRequest.setEndpoint(avMdtGeneratePdfEndPoint.value__c+cisItem);
                HTTPResponse res = docHttp.send(docRequest);
                System.debug('@@@ after res ');
                if(res.getStatusCode() == 200)
                {
                    System.debug('111 is 200');
                    Map<String, Object> resultsMap = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
                    if(!resultsMap.isEmpty())
                    {
                        docIdPaaListMap.put(String.valueOf(resultsMap.get('document_id')),cisIdPaaListMap.get(cisItem));
                        System.debug('docIdPaaListMap '+docIdPaaListMap);
                    }
                }
                else 
                {
                    System.debug('inside not 200 what is the cis Item' +cisItem);
                    errIdList.add(cisItem);
                    errMsgList.add(res.getStatus());
                    System.debug('status code '+res.getStatusCode());
                }
            }
2
  • 3
    I would avoid making callouts synchronously in a for-loop if at all possible. I am not certain about your use case, but a more practical architecture would likely be to make one callout per queueable (so your batch enqueues multiple queueables that make the callout in their own transactions). Continuations are worth looking at as is this Queueable pattern on The Joys of Apex.
    – nbrown
    Commented Dec 7, 2023 at 14:20
  • batch should enqueue a queueable with a collection, the queueable should take the first from the list, do the callout, and then enqueue itself again with the remaining list. Simple patter, easy to test, extensible to building retry mechanism on callout error
    – cropredy
    Commented Dec 7, 2023 at 16:28

0

You must log in to answer this question.

Browse other questions tagged .