First error: Exceeded maximum time allotted for callout (120000 ms)


.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
1
down vote
favorite
I have a Batch class making an API callout and I have scheduled this class. I have used a for loop to iterate through the page number variable in my API endpoint. There are 64 pages. Strangely, if I use for(integer i=1; i<=64;i++) I get an error, but it works perfectly fine with for(integer i=1; i<=35;i++) or any lower value than 35 for i. I have tried changing my batch size but doesn't help.
These are my classes:
Batch Class:
global class ImportReports implements Database.Batchable<Reports__c>, Database.AllowsCallouts
global static HTTPResponse getReports(String api)
HttpRequest req = new HttpRequest();
req.setEndpoint(api);
req.setMethod('GET');
req.setTimeout(120000);
Http http = new Http();
HTTPResponse res = http.send(req);
return res;
global List<Reports__c> start(Database.BatchableContext BC)
List<Reports__c> reportsToAdd = new List<Reports__c>();
for(integer i=1; i<=32;i++)
String allReportsString = getReports('https://api.example.com/v1/reports/page[number]='+i).getBody();
WrapperClass allReports = WrapperClass.parse(recentReports);
for(WrapperClass reportInArray : allReports)
Reports__c rep = new Reports__c();
rep.id__c = reportInArray.id;
reportsToAdd.add(rep);
System.debug(reportInArray.id);
return reportsToAdd;
global void execute(Database.BatchableContext BC, List<Reports__c> scope)
try
upsert scope;
catch (DmlException e)
// Process exception here
global void finish(Database.BatchableContext BC)
Scheduling Class:
global class SchedulerClass implements Schedulable, Database.AllowsCallouts
public static String sched = '0 11 11 * * ?';
global static String scheduleBatch()
SchedulerClass SC = new SchedulerClass();
return System.schedule('Insert Reports', sched, SC);
global void execute(SchedulableContext sc)
ImportReports b = new ImportReports ();
ID batchprocessid = Database.executeBatch(b,50);
How can I resolve this error?
apex batch callout schedulebatch timeout
add a comment |Â
up vote
1
down vote
favorite
I have a Batch class making an API callout and I have scheduled this class. I have used a for loop to iterate through the page number variable in my API endpoint. There are 64 pages. Strangely, if I use for(integer i=1; i<=64;i++) I get an error, but it works perfectly fine with for(integer i=1; i<=35;i++) or any lower value than 35 for i. I have tried changing my batch size but doesn't help.
These are my classes:
Batch Class:
global class ImportReports implements Database.Batchable<Reports__c>, Database.AllowsCallouts
global static HTTPResponse getReports(String api)
HttpRequest req = new HttpRequest();
req.setEndpoint(api);
req.setMethod('GET');
req.setTimeout(120000);
Http http = new Http();
HTTPResponse res = http.send(req);
return res;
global List<Reports__c> start(Database.BatchableContext BC)
List<Reports__c> reportsToAdd = new List<Reports__c>();
for(integer i=1; i<=32;i++)
String allReportsString = getReports('https://api.example.com/v1/reports/page[number]='+i).getBody();
WrapperClass allReports = WrapperClass.parse(recentReports);
for(WrapperClass reportInArray : allReports)
Reports__c rep = new Reports__c();
rep.id__c = reportInArray.id;
reportsToAdd.add(rep);
System.debug(reportInArray.id);
return reportsToAdd;
global void execute(Database.BatchableContext BC, List<Reports__c> scope)
try
upsert scope;
catch (DmlException e)
// Process exception here
global void finish(Database.BatchableContext BC)
Scheduling Class:
global class SchedulerClass implements Schedulable, Database.AllowsCallouts
public static String sched = '0 11 11 * * ?';
global static String scheduleBatch()
SchedulerClass SC = new SchedulerClass();
return System.schedule('Insert Reports', sched, SC);
global void execute(SchedulableContext sc)
ImportReports b = new ImportReports ();
ID batchprocessid = Database.executeBatch(b,50);
How can I resolve this error?
apex batch callout schedulebatch timeout
add a comment |Â
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I have a Batch class making an API callout and I have scheduled this class. I have used a for loop to iterate through the page number variable in my API endpoint. There are 64 pages. Strangely, if I use for(integer i=1; i<=64;i++) I get an error, but it works perfectly fine with for(integer i=1; i<=35;i++) or any lower value than 35 for i. I have tried changing my batch size but doesn't help.
These are my classes:
Batch Class:
global class ImportReports implements Database.Batchable<Reports__c>, Database.AllowsCallouts
global static HTTPResponse getReports(String api)
HttpRequest req = new HttpRequest();
req.setEndpoint(api);
req.setMethod('GET');
req.setTimeout(120000);
Http http = new Http();
HTTPResponse res = http.send(req);
return res;
global List<Reports__c> start(Database.BatchableContext BC)
List<Reports__c> reportsToAdd = new List<Reports__c>();
for(integer i=1; i<=32;i++)
String allReportsString = getReports('https://api.example.com/v1/reports/page[number]='+i).getBody();
WrapperClass allReports = WrapperClass.parse(recentReports);
for(WrapperClass reportInArray : allReports)
Reports__c rep = new Reports__c();
rep.id__c = reportInArray.id;
reportsToAdd.add(rep);
System.debug(reportInArray.id);
return reportsToAdd;
global void execute(Database.BatchableContext BC, List<Reports__c> scope)
try
upsert scope;
catch (DmlException e)
// Process exception here
global void finish(Database.BatchableContext BC)
Scheduling Class:
global class SchedulerClass implements Schedulable, Database.AllowsCallouts
public static String sched = '0 11 11 * * ?';
global static String scheduleBatch()
SchedulerClass SC = new SchedulerClass();
return System.schedule('Insert Reports', sched, SC);
global void execute(SchedulableContext sc)
ImportReports b = new ImportReports ();
ID batchprocessid = Database.executeBatch(b,50);
How can I resolve this error?
apex batch callout schedulebatch timeout
I have a Batch class making an API callout and I have scheduled this class. I have used a for loop to iterate through the page number variable in my API endpoint. There are 64 pages. Strangely, if I use for(integer i=1; i<=64;i++) I get an error, but it works perfectly fine with for(integer i=1; i<=35;i++) or any lower value than 35 for i. I have tried changing my batch size but doesn't help.
These are my classes:
Batch Class:
global class ImportReports implements Database.Batchable<Reports__c>, Database.AllowsCallouts
global static HTTPResponse getReports(String api)
HttpRequest req = new HttpRequest();
req.setEndpoint(api);
req.setMethod('GET');
req.setTimeout(120000);
Http http = new Http();
HTTPResponse res = http.send(req);
return res;
global List<Reports__c> start(Database.BatchableContext BC)
List<Reports__c> reportsToAdd = new List<Reports__c>();
for(integer i=1; i<=32;i++)
String allReportsString = getReports('https://api.example.com/v1/reports/page[number]='+i).getBody();
WrapperClass allReports = WrapperClass.parse(recentReports);
for(WrapperClass reportInArray : allReports)
Reports__c rep = new Reports__c();
rep.id__c = reportInArray.id;
reportsToAdd.add(rep);
System.debug(reportInArray.id);
return reportsToAdd;
global void execute(Database.BatchableContext BC, List<Reports__c> scope)
try
upsert scope;
catch (DmlException e)
// Process exception here
global void finish(Database.BatchableContext BC)
Scheduling Class:
global class SchedulerClass implements Schedulable, Database.AllowsCallouts
public static String sched = '0 11 11 * * ?';
global static String scheduleBatch()
SchedulerClass SC = new SchedulerClass();
return System.schedule('Insert Reports', sched, SC);
global void execute(SchedulableContext sc)
ImportReports b = new ImportReports ();
ID batchprocessid = Database.executeBatch(b,50);
How can I resolve this error?
apex batch callout schedulebatch timeout
edited Aug 7 at 20:58


Adrian Larsonâ¦
99.4k19104220
99.4k19104220
asked Aug 7 at 18:28


Sneha Jagtap
213
213
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
4
down vote
The callout timeout is tricky, because it applies both to single callouts and as a cumulative limit across a transaction:
The maximum cumulative timeout for callouts by a single Apex transaction is 120 seconds. This time is additive across all callouts invoked by the Apex transaction.
Here, it looks like you're running into the cumulative version of this limit. You can send up to ~35 (the number probably varies slightly depending on network speed and server load) callouts in a single transaction because each one takes a little under 4 seconds, on average, to complete.
You're currently doing all of this work in your start()
method. You need to make some architectural changes to split this work across multiple transactions in order to complete it successfully. start()
runs in a single transaction, and is intended to return a query or iterator that defines the objects which will be split into separate batches, each of which is processed via execute()
in a separate transaction.
Inasmuch as you're not iterating over batches of sObjects, I would actually suggest making this into a Queueable chain rather than a batch class. Basically, what you'd do is make a Queueable Apex class like this:
public class MyQueueable implements Queueable
Integer startNumber = 0;
Integer endNumber = 0;
public MyQueueable(Integer start, Integer end)
startNumber = start;
endNumber = end;
public void execute(QueueableContext context)
// make your callouts here -
// process, say, 30, then chain into a new Queueable:
for (Integer i = startNumber; i < endNumber && i < startNumber + 30; i++)
// Do callout and store result
insert results; // however we accumulated them.
// Check if we have more work to do and recurse.
if (i < endNumber)
System.enqueueJob(new MyQueueable(startNumber + i, endNumber));
This is a very rough sketch, but I think the pattern will be more applicable to your challenge than Batch Apex as you're trying to use it.
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
4
down vote
The callout timeout is tricky, because it applies both to single callouts and as a cumulative limit across a transaction:
The maximum cumulative timeout for callouts by a single Apex transaction is 120 seconds. This time is additive across all callouts invoked by the Apex transaction.
Here, it looks like you're running into the cumulative version of this limit. You can send up to ~35 (the number probably varies slightly depending on network speed and server load) callouts in a single transaction because each one takes a little under 4 seconds, on average, to complete.
You're currently doing all of this work in your start()
method. You need to make some architectural changes to split this work across multiple transactions in order to complete it successfully. start()
runs in a single transaction, and is intended to return a query or iterator that defines the objects which will be split into separate batches, each of which is processed via execute()
in a separate transaction.
Inasmuch as you're not iterating over batches of sObjects, I would actually suggest making this into a Queueable chain rather than a batch class. Basically, what you'd do is make a Queueable Apex class like this:
public class MyQueueable implements Queueable
Integer startNumber = 0;
Integer endNumber = 0;
public MyQueueable(Integer start, Integer end)
startNumber = start;
endNumber = end;
public void execute(QueueableContext context)
// make your callouts here -
// process, say, 30, then chain into a new Queueable:
for (Integer i = startNumber; i < endNumber && i < startNumber + 30; i++)
// Do callout and store result
insert results; // however we accumulated them.
// Check if we have more work to do and recurse.
if (i < endNumber)
System.enqueueJob(new MyQueueable(startNumber + i, endNumber));
This is a very rough sketch, but I think the pattern will be more applicable to your challenge than Batch Apex as you're trying to use it.
add a comment |Â
up vote
4
down vote
The callout timeout is tricky, because it applies both to single callouts and as a cumulative limit across a transaction:
The maximum cumulative timeout for callouts by a single Apex transaction is 120 seconds. This time is additive across all callouts invoked by the Apex transaction.
Here, it looks like you're running into the cumulative version of this limit. You can send up to ~35 (the number probably varies slightly depending on network speed and server load) callouts in a single transaction because each one takes a little under 4 seconds, on average, to complete.
You're currently doing all of this work in your start()
method. You need to make some architectural changes to split this work across multiple transactions in order to complete it successfully. start()
runs in a single transaction, and is intended to return a query or iterator that defines the objects which will be split into separate batches, each of which is processed via execute()
in a separate transaction.
Inasmuch as you're not iterating over batches of sObjects, I would actually suggest making this into a Queueable chain rather than a batch class. Basically, what you'd do is make a Queueable Apex class like this:
public class MyQueueable implements Queueable
Integer startNumber = 0;
Integer endNumber = 0;
public MyQueueable(Integer start, Integer end)
startNumber = start;
endNumber = end;
public void execute(QueueableContext context)
// make your callouts here -
// process, say, 30, then chain into a new Queueable:
for (Integer i = startNumber; i < endNumber && i < startNumber + 30; i++)
// Do callout and store result
insert results; // however we accumulated them.
// Check if we have more work to do and recurse.
if (i < endNumber)
System.enqueueJob(new MyQueueable(startNumber + i, endNumber));
This is a very rough sketch, but I think the pattern will be more applicable to your challenge than Batch Apex as you're trying to use it.
add a comment |Â
up vote
4
down vote
up vote
4
down vote
The callout timeout is tricky, because it applies both to single callouts and as a cumulative limit across a transaction:
The maximum cumulative timeout for callouts by a single Apex transaction is 120 seconds. This time is additive across all callouts invoked by the Apex transaction.
Here, it looks like you're running into the cumulative version of this limit. You can send up to ~35 (the number probably varies slightly depending on network speed and server load) callouts in a single transaction because each one takes a little under 4 seconds, on average, to complete.
You're currently doing all of this work in your start()
method. You need to make some architectural changes to split this work across multiple transactions in order to complete it successfully. start()
runs in a single transaction, and is intended to return a query or iterator that defines the objects which will be split into separate batches, each of which is processed via execute()
in a separate transaction.
Inasmuch as you're not iterating over batches of sObjects, I would actually suggest making this into a Queueable chain rather than a batch class. Basically, what you'd do is make a Queueable Apex class like this:
public class MyQueueable implements Queueable
Integer startNumber = 0;
Integer endNumber = 0;
public MyQueueable(Integer start, Integer end)
startNumber = start;
endNumber = end;
public void execute(QueueableContext context)
// make your callouts here -
// process, say, 30, then chain into a new Queueable:
for (Integer i = startNumber; i < endNumber && i < startNumber + 30; i++)
// Do callout and store result
insert results; // however we accumulated them.
// Check if we have more work to do and recurse.
if (i < endNumber)
System.enqueueJob(new MyQueueable(startNumber + i, endNumber));
This is a very rough sketch, but I think the pattern will be more applicable to your challenge than Batch Apex as you're trying to use it.
The callout timeout is tricky, because it applies both to single callouts and as a cumulative limit across a transaction:
The maximum cumulative timeout for callouts by a single Apex transaction is 120 seconds. This time is additive across all callouts invoked by the Apex transaction.
Here, it looks like you're running into the cumulative version of this limit. You can send up to ~35 (the number probably varies slightly depending on network speed and server load) callouts in a single transaction because each one takes a little under 4 seconds, on average, to complete.
You're currently doing all of this work in your start()
method. You need to make some architectural changes to split this work across multiple transactions in order to complete it successfully. start()
runs in a single transaction, and is intended to return a query or iterator that defines the objects which will be split into separate batches, each of which is processed via execute()
in a separate transaction.
Inasmuch as you're not iterating over batches of sObjects, I would actually suggest making this into a Queueable chain rather than a batch class. Basically, what you'd do is make a Queueable Apex class like this:
public class MyQueueable implements Queueable
Integer startNumber = 0;
Integer endNumber = 0;
public MyQueueable(Integer start, Integer end)
startNumber = start;
endNumber = end;
public void execute(QueueableContext context)
// make your callouts here -
// process, say, 30, then chain into a new Queueable:
for (Integer i = startNumber; i < endNumber && i < startNumber + 30; i++)
// Do callout and store result
insert results; // however we accumulated them.
// Check if we have more work to do and recurse.
if (i < endNumber)
System.enqueueJob(new MyQueueable(startNumber + i, endNumber));
This is a very rough sketch, but I think the pattern will be more applicable to your challenge than Batch Apex as you're trying to use it.
answered Aug 7 at 18:54


David Reed
17.7k21540
17.7k21540
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f228056%2ffirst-error-exceeded-maximum-time-allotted-for-callout-120000-ms%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password