function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
sanju21sanju21 

Apex general call out limitations and future annotation limitations

We have a requirement from client where we need to poll an outside server every hour and update leads in SF based on some status change. We are doing Http request and getting a http response and because it is a scheduled class, I am using Future annotation.

 

The plan is to do apex call outs based on some Application ID custom  field in Leads. It should have all worked perfectly but I stumbled upon Apex call out limitations and Apex future annotation limitations.

 

Apex call out limitations say:

 

The following limits apply when an Apex script makes a callout to an HTTP request or a Web services call. The Web services call can be a Web services API call or any external Web services call.

  • A single Apex transaction can make a maximum of 10 callouts to an HTTP request or an API call.

Which means I can poll for only 10 leads(1 call out per lead because I am polling based on lead Id) at a time? This approach would not work if I want to poll for 100 leads at a time. So I am stuck. The client can over come Future annotation limitation by probably buying more licenses. But how can I overcome this general limitation of apex call outs?? Any ideas, suggestions??

 

Pleaaaaaaaaaaaase help!!!!!!

Best Answer chosen by Admin (Salesforce Developers) 
BritishBoyinDCBritishBoyinDC

So remove the limit 1 in the SOQL, and change the call to to the batch to be:

 

 

Database.executeBatch(runPoll,1);

 

That will pass in all the leads that match the criteria one at a time into the batch. You can also change the update in the batch to just update the lead being processed. Again, because it is a batch, you don't have to worry about DML limits etc...

 

All Answers

BritishBoyinDCBritishBoyinDC

Do it via a Batch - each iteration of the batch resets the limit, so set the batch to process one record at a time, and pass the leads you want to process into the batch.

 

I do this to update BitLy stats via a callout, and it can process several hundred records...

sanju21sanju21

Hey! long time!! Thank you so much for the response..

 

Okay, here is what I tried from what I understood...but this is not working...I dont know how I can execute all leads by passing one at a time..but this is what I tried..

 

I created a schedulable  class that I can schedule to run, which in turn executes my batch

 

global class schedulePollingForStatusUpdates implements Schedulable {	
  	global void execute(SchedulableContext SC) {   	
  			     		
     		batchablePollingForStatusUpdates runPoll = new batchablePollingForStatusUpdates();
   			runPoll.query= 'SELECT Name, Id, Email, phone, firstname, lastname, state, city, company, street,'+
	                			'from Lead where'+
	                			' Application_Status__c <> \'Withdrawn\' AND '+ 
	                			'Application_Status__c <> null AND ApplicationID__c <> null AND Name like \'test%\' limit 1';
	        Database.executeBatch(runPoll);
	        
	    
     		
  	}
  	
  	
}

 

 And then I created a batchable  class

 

global class batchablePollingForStatusUpdates implements Database.Batchable<sObject>, 
 Database.AllowsCallouts {
 	
public String query;
String email;
Id toUserId;
Id fromUserId;

global database.querylocator start(Database.BatchableContext BC){
            return Database.getQueryLocator(query);}

global void execute(Database.BatchableContext BC, List<sObject> scope){
        
     	List<Lead> upLeads = new List<Lead>();
	String endpoint= //server url
		
   	for(sObject s : scope){
   		Lead n = (Lead)s;

        	    	if (n.applicationID__c != '' && n.applicationID__c != null){

			string endurl = endpoint+'&ApplicationID='+ n.applicationID__c;
	    		
	    		HttpResponse response = InvokeServer.InvokeServer('GET', endurl, '');
								
				// process leads and add leads
				// to be updated to upLeads
									  
	 }
	update upLeads;
}    .......

 

But only one lead is processed by this code...how can I get the batch to process all leads...?

 

BritishBoyinDCBritishBoyinDC

So remove the limit 1 in the SOQL, and change the call to to the batch to be:

 

 

Database.executeBatch(runPoll,1);

 

That will pass in all the leads that match the criteria one at a time into the batch. You can also change the update in the batch to just update the lead being processed. Again, because it is a batch, you don't have to worry about DML limits etc...

 

This was selected as the best answer
sanju21sanju21

Hey, that works beautifully! You are awesome, thank you so much!! :)

BritishBoyinDCBritishBoyinDC

Hapyp to help - big fan of batch apex!

sanju21sanju21

Hey, one small question...Batch governor limits say:

 

  • Up to five queued or active batch jobs are allowed for Apex.
  •  

    Where would this come into picture? When I schedule the batch to run? I mean, can I schedule the class to run every hour and query some hundreds of leads

    and callouts respectively without any problem, this way? I am asking because if I am passing one lead per batch, I might be using some hundreds of batches every hour.

    I think when the new batch comes up the old batch is freed up by that time already,  right?

BritishBoyinDCBritishBoyinDC

I don't think you need to worry about that...

 

When it says active batches, I believe it refers to the whole batch - so processing 500 leads = one active batch, which then has 500 iterations of the batch.

 

 

sanju21sanju21

Sounds great, thank you!! :)