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
paul-lmipaul-lmi 

Scheduled Apex and HTTP Callouts

Is this supported?  We're using the Twitter app, and I wrote a schedulable class that calls the AutomationWrapper included in this package to update our conversations every ten minutes.  The code in my class executes on its own as expected, but when it's run via the scheduler, it appears that the HTTP callouts are simply skipped.

 

This is the log.  This code takes an absolute minimum of 2 full seconds to execute when working properly.  When run from the scheduler, its' done in less than 300ms, which leads me to believe that the HTTP callouts are just being skipped.

 

 

18.0 APEX_CODE,DEBUG;APEX_PROFILING,INFO;CALLOUT,INFO;DB,INFO;VALIDATION,INFO;WORKFLOW,INFO1:30:0.26|EXECUTION_STARTED1:30:0.26|CODE_UNIT_STARTED|[EXTERNAL]Twitter Synch 41:30:0.41|SOQL_EXECUTE_BEGIN|[4,40]|Aggregations:0|select id from sf4twitter__twitter_account__c where name = 'logmeinhelp' limit 11:30:0.48|SOQL_EXECUTE_END|[4,40]|Rows:1|Duration:71:30:0.49|METHOD_ENTRY|[5,14]|sf4twitter.AutomationWrapper.doSearchAccount(Id, Integer)1:30:0.49|ENTERING_MANAGED_PKG|sf4twitter1:30:0.49|SOQL_EXECUTE_BEGIN|[116,42]|Aggregations:0| Select t.Username__c, t.Unknown_Twitter_Usernames__c, t.Twitter_User_Id__c, t.Twitter_Max_Twitter__c, t.Twitter_Max_Message__c, t.SystemModstamp, t.Password__c, t.OwnerId, t.Name, t.LastModifiedDate, t.LastModifiedById, t.IsDeleted, t.Id, t.Enable_Auto_Case_Creation__c, t.CreatedDate, t.CreatedById, t.Bit_ly_Username__c, t.Bit_ly_Password__c, associate_DM__c , ignore_maxid__c, closed_case_duration__c From Twitter_Account__c t Where Id =:taId 1:30:0.58|SOQL_EXECUTE_END|[116,42]|Rows:1|Duration:91:30:0.59|SOQL_EXECUTE_BEGIN|[27,34]|Aggregations:0|select id, name from Account where name = :Label.TWITTER_ACCOUNT_NAME1:30:0.114|SOQL_EXECUTE_END|[27,34]|Rows:0|Duration:551:30:0.115|SOQL_EXECUTE_BEGIN|[60,21]|Aggregations:0|Select Name, Id, OwnerId, Username__c, Unknown_Twitter_Usernames__c, Password__c, Twitter_Max_Message__c, Enable_Auto_Case_Creation__c, Bit_ly_Username__c, Bit_ly_Password__c, Twitter_Max_Twitter__c, associate_DM__c, associate_cases_same_username__c, closed_case_duration__c From Twitter_Account__c LIMIT 10001:30:0.118|SOQL_EXECUTE_END|[60,21]|Rows:2|Duration:31:30:0.132|SOQL_EXECUTE_BEGIN|[156,17]|Aggregations:0|select id, twitterId__c from Case where twitterId__c in :tids1:30:0.136|SOQL_EXECUTE_END|[156,17]|Rows:0|Duration:41:30:0.139|SOQL_EXECUTE_BEGIN|[399,20]|Aggregations:0|select id, twitter_username__c from Contact where twitter_username__c in :twitterUserNames LIMIT 10001:30:0.142|SOQL_EXECUTE_END|[399,20]|Rows:0|Duration:31:30:0.142|SOQL_EXECUTE_BEGIN|[402,17]|Aggregations:0|select id, twitter_username__c from Lead where IsConverted = false and twitter_username__c in :twitterUserNames LIMIT 10001:30:0.153|SOQL_EXECUTE_END|[402,17]|Rows:0|Duration:111:30:0.153|SOQL_EXECUTE_BEGIN|[361,18]|Aggregations:0|Select Id, twitterID__c, ContactId, Twitter_Username__c from Case where twitterID__c in :twitterIds1:30:0.155|SOQL_EXECUTE_END|[361,18]|Rows:0|Duration:21:30:0.156|SOQL_EXECUTE_BEGIN|[366,40]|Aggregations:0|select Id, Case__c, Case__r.ClosedDate, Case__r.Status, Contact__c, twitterid__c, Parent__c, type__c from Twitter_Conversation__c where twitterid__c in :twitterIds LIMIT 10001:30:0.164|SOQL_EXECUTE_END|[366,40]|Rows:0|Duration:81:30:0.164|SOQL_EXECUTE_BEGIN|[371,40]|Aggregations:0|select Id, Case__c, Case__r.ClosedDate, Case__r.Status, Contact__c, twitterid__c, Parent__c, Content__c, Author_Real_Name__c, Author_Name__c, type__c, In_Reply_To_Status_Id__c, In_Reply_To_User_Id__c from Twitter_Conversation__c where twitterid__c in :twitterReply LIMIT 10001:30:0.168|SOQL_EXECUTE_END|[371,40]|Rows:0|Duration:41:30:0.171|SOQL_EXECUTE_BEGIN|[663,18]|Aggregations:0|select id, twitterId__c, Twitter_Username__c, CreatedDate, ContactId, Contact.Twitter_Username__c from Case where ((Status != :Label.TWITTER_CASE_CLOSED or ClosedDate >= :closeDuration) and Twitter_Username__c IN :fromUsernames) or Id IN :repCasesId order by LastModifiedDate desc LIMIT 10001:30:0.181|SOQL_EXECUTE_END|[663,18]|Rows:0|Duration:101:30:0.181|SOQL_EXECUTE_BEGIN|[677,40]|Aggregations:0|select id, Content__c,Case__c, Parent__c, Author_Name__c from Twitter_Conversation__c where Case__c IN :casesIds LIMIT 10001:30:0.183|SOQL_EXECUTE_END|[677,40]|Rows:0|Duration:21:30:0.183|SOQL_EXECUTE_BEGIN|[705,36]|Aggregations:0|select In_Reply_To_Status_Id__c, id, Case__r.Status, Case__r.twitterId__c, Case__r.Twitter_Username__c, Case__r.CreatedDate, Case__r.ContactId, Author_Name__c from Twitter_Conversation__c where (In_Reply_To_Status_Id__c in :repliedRAStatusTwitterIds) and (Case__r.Status != :Label.TWITTER_CASE_CLOSED or Case__r.ClosedDate >= :closeDuration) order by Case__r.LastModifiedDate desc limit 10001:30:0.187|SOQL_EXECUTE_END|[705,36]|Rows:0|Duration:41:30:0.188|DML_BEGIN|[621,42]|Op:Upsert|Type:Case|Rows:01:30:0.188|DML_END|[621,42]|1:30:0.190|SOQL_EXECUTE_BEGIN|[561,20]|Aggregations:0|select id, twitter_username__c from Contact where twitter_username__c in :twitterUserNames LIMIT 10001:30:0.192|SOQL_EXECUTE_END|[561,20]|Rows:0|Duration:21:30:0.192|DML_BEGIN|[583,42]|Op:Upsert|Type:Case|Rows:01:30:0.193|DML_END|[583,42]|1:30:0.193|SOQL_EXECUTE_BEGIN|[411,42]|Aggregations:0|select TwitterID__c, Twitter_Account__c, Direct_Message__c,type__c from Twitter_Conversation__c where Type__c = :Label.TWITTER_TYPE_REPLIES and Twitter_Account__c in :accounts.keySet() order by TwitterID__c desc limit 11:30:0.201|SOQL_EXECUTE_END|[411,42]|Rows:1|Duration:81:30:0.201|SOQL_EXECUTE_BEGIN|[414,51]|Aggregations:0|select TwitterID__c, Twitter_Account__c, Direct_Message__c,type__c from Twitter_Conversation__c where Type__c = :Label.TWITTER_OUTBOUND_DIRECTMESSAGE and Twitter_Account__c in :accounts.keySet() and Direct_Message__c != null order by TwitterID__c desc limit 11:30:0.205|SOQL_EXECUTE_END|[414,51]|Rows:0|Duration:41:30:0.205|SOQL_EXECUTE_BEGIN|[418,45]|Aggregations:0|select TwitterID__c, Twitter_Account__c, Direct_Message__c,type__c from Twitter_Conversation__c where (Type__c = :Label.TWITTER_TYPE_REGISTERED_ACCOUNT or Type__c = :Label.TWITTER_OUTBOUND_REPLY) and Twitter_Account__c in :accounts.keySet() and Direct_Message__c = null order by TwitterID__c desc limit 11:30:0.211|SOQL_EXECUTE_END|[418,45]|Rows:1|Duration:61:30:0.211|SOQL_EXECUTE_BEGIN|[422,41]|Aggregations:0|select TwitterID__c, Twitter_Account__c, Direct_Message__c,type__c from Twitter_Conversation__c where Type__c = :Label.TWITTER_TYPE_DIRECT_MESSAGE and Twitter_Account__c in :accounts.keySet() order by TwitterID__c desc limit 11:30:0.215|SOQL_EXECUTE_END|[422,41]|Rows:0|Duration:41:30:0.218|DML_BEGIN|[443,3]|Op:Update|Type:sf4twitter__Twitter_Account__c|Rows:11:30:0.238|ENTERING_MANAGED_PKG|sf4twitter1:30:0.238|SOQL_EXECUTE_BEGIN|[5,42]|Aggregations:0|select id, Username__c from Twitter_Account__c where Username__c =: Trigger.new[0].Username__c and ownerId = :UserInfo.getUserId()1:30:0.243|SOQL_EXECUTE_END|[5,42]|Rows:1|Duration:51:30:0.243|CUMULATIVE_LIMIT_USAGE1:30:0.243|CUMULATIVE_LIMIT_USAGE_END1:30:0.256|DML_END|[443,3]|1:30:0.257|METHOD_EXIT|[5,14]|doSearchAccount(Id, Integer)1:30:0.257|METHOD_ENTRY|[6,3]|system.debug(String)1:30:0.258|USER_DEBUG|[6,3]|DEBUG|result: <?xml version="1.0" encoding="UTF-8"?><result><conversations>0</conversations><cases>0</cases><caseComments>0</caseComments><contacts>0</contacts><leads>0</leads><errorCode>null</errorCode><errorMsg>null</errorMsg><pageNumber>0</pageNumber></result>1:30:0.258|METHOD_EXIT|[6,3]|debug(ANY)1:30:0.258|CODE_UNIT_FINISHED1:30:0.258|EXECUTION_FINISHED

 

 The scheduler class that I'm running every 10 minutes

 

global class SynchTwitter Implements Schedulable{ global void Execute(SchedulableContext SC){ sf4twitter__twitter_account__c acc = [select id from sf4twitter__twitter_account__c where name = 'mytwitteraccountname' limit 1]; string s = sf4twitter.automationwrapper.doSearchAccount(acc.id,0); system.debug('result: ' + s); }}

 

 I let this run for an hour, and no results were ever pulled back.  I ran the code inside the execute method on its own via the system log window, and it pulled back the conversations I was expected to be pulled.

 

The documentation for the Spring '10 release does not indicate that HTTP callouts are not supported in Scheduled Apex.  I'm not willing to write a complete class just to confirm whether or not it's supported, and I can't see any issues with the Twitter class debug log (it's a managed package, so I can't see what's being done where). 

 

Please advise. 

 

 

Michael_KahleMichael_Kahle

Hi paul-lmi,

 

no Web Callouts are not supported inside a Scheduled Apex Run. You can see the ErrorLog inthe Debuglogs it clearly says, that during a scheduled Run an WebCallout can not be done.

If you only do up to 10 Callaouts per Scheduled Run, you can use a Future Method to do the Callout. This however will not run with Batch runs which are making Callouts.

paul-lmipaul-lmi
Great, so since this is a managed package, it just can't be done at all.  Getting really tired of the limitations put on every new feature that comes out.  HTTP callouts only seem to be supported if the end user is sitting there, and clicks something, and then fires it.  Don't they get the fact that we want to remove work from the user's workflow?
JerryHJerryH

I'm apparently operating under the same delusion.  Just coded up the same kind of scenario (callout to a REST service on a scheduled basis) and I'm not seeing anything happen either. :-\

 

Any work-arounds for this?

 

Jerry H.

 

paul-lmipaul-lmi

Not being constructive here, but I really need to vent.  Why, oh why, would Salesforce develop any app geared at social integration/interaction, that doesn't support real time, and scheduled, actions to occur in a speedy manner?  The Twitter integration requires custom indexes to be created on 3 objects in SF if the customer's org is large, yet those aren't documented at all and getting that done is like pulling teeth, but worse.  Fine, workaround, schedule the actions instead of forcing the user to do them.  Great.  Nope.  Can't even do that because callouts are just blatantly SKIPPED in the scheduled Apex code.

 

Does Salesforce actually think all our users are sitting there, in front of the app, hitting refresh?  I certainly hope not...

 

Expecting admins to kick off some kind of scheduled process in a third party scheduler is ridiculous.  We use Salesforce because we don't want to deal with maintaining off-platform functionality.  We can get past the fact that Salesforce will likely never give us full CRON-like functionality (BTW, scheduled Apex is NOT CRON, marketing, kthnx), if you just take a leap of faith on the fact that in order to schedule Apex we already have to go through a number of hoops that are reducing the potential for your users to take down OUR platform.

 

</rant>

ContinousImprovementContinousImprovement

Hi Paul,

 

Just wanted to know, Is there any other way to get the http callouts from scheduler.

I am also facing the same problem that my scheduler is also  not fetching any data for twitter accounts.

 

Just a guess, can we use any other scheduler for this, like cronkit, boomi, etc.

 

Will they work for twitter implementation.

 

Any help is appreciated.

 

paul-lmipaul-lmi

use an @future method for your callout and it'll work.  it's not an ideal solution, but it can be done.

ContinousImprovementContinousImprovement

Thanks Paul that worked.

 

The below code works fine when I am searching for 1st page. Now when I am searching for next page I am getting following error:

 

<errorMsg>You have uncommitted work pending. Please commit or rollback before calling out</errorMsg>

Please help how can I search for another page by calling the below method again and again.

 

sf4twitter.automationwrapper.doSearchKeyword(twitsearch.id,pageNo);

 

 

I need to search till end. Please advice.

 

 

Below is code which I am running to search world cup tweet results:

 

global class SynchTwitterSearchWorldCup Implements Schedulable{
 global void Execute(SchedulableContext SC){
  doSynch();
 }

 @future (callout=true)  
 static void doSynch(){

            sf4twitter__Twitter_Search__c twitsearch= [SELECT Id, Name, sf4twitter__Twitter_Keyword_Search__c FROM sf4twitter__Twitter_Search__c where name ='WorldCup' limit 1];
            system.debug('tsearch : ' + twitsearch.name + ' and ID '+ twitsearch.id + ' and Keyword: '+ twitsearch.sf4twitter__Twitter_Keyword_Search__c);
            
            string s =sf4twitter.automationwrapper.doSearchKeyword(twitsearch.id, 1);
             system.debug('result for Search - '+ twitsearch.name +': '  + s );
 
            //Not Working - Doing Nothing but delay so that previous records gets commited
            //Integer start = System.Now().millisecond();
            //while(System.Now().millisecond()< start+150){
            //}
            
            if(s != null && s.indexOf('</pageNumber>', 0) != -1)
            {
                Integer pageNo = integer.valueof(s.substring(s.indexOf('<pageNumber>', 0) +12, s.indexOf('</pageNumber>', 0))) ;
                system.debug('pageNo : ' + pageNo );  
                while(pageNo >0){
                
                string subPages = sf4twitter.automationwrapper.doSearchKeyword(twitsearch.id,pageNo);
                system.debug('result for SubPages for ' + twitsearch.name + 'for Page: ' + pageNo + ': '+ subPages );  
    
                pageNo = integer.valueof(subPages.substring(subPages.indexOf('<pageNumber>', 0) +12, subPages.indexOf('</pageNumber>', 0)));
                system.debug('pageNo for subpages returned: ' + pageNo );  
                }
            }
    }
}

 

 

And the log is as follows:

 

Log

19.0 APEX_CODE,DEBUG;APEX_PROFILING,INFO;CALLOUT,INFO;DB,INFO;VALIDATION,INFO;WORKFLOW,INFO
16:55:0.198|EXECUTION_STARTED
16:55:0.198|CODE_UNIT_STARTED|[EXTERNAL]|01p900000004pSs|SynchTwitterSearchWorldCup.doSynch
16:55:0.199|SOQL_EXECUTE_BEGIN|[12,55]|Aggregations:0|SELECT Id, Name, sf4twitter__Twitter_Keyword_Search__c FROM sf4twitter__Twitter_Search__c where name ='WorldCup' limit 1
16:55:0.204|SOQL_EXECUTE_END|[12,55]|Rows:1
16:55:0.205|METHOD_ENTRY|[13,13]|system.debug(String)
16:55:0.205|USER_DEBUG|[13,13]|DEBUG|tsearch : WorldCup and ID a0690000001JJm3AAG and Keyword: world cup
16:55:0.205|METHOD_EXIT|[13,13]|system.debug(String)
16:55:0.205|METHOD_ENTRY|[15,23]|01p900000004nXS|sf4twitter.AutomationWrapper.doSearchKeyword(Id, Integer)
16:55:0.205|ENTERING_MANAGED_PKG|sf4twitter
16:55:0.205|SOQL_EXECUTE_BEGIN|[169,44]|Aggregations:0|
Select t.Weight__c, t.Unknown_Twitter_Usernames__c, t.Twitter_Max_Search__c,
t.Twitter_Keyword_Search__c, t.SystemModstamp, t.OwnerId, t.Name, t.LastModifiedDate,
t.LastModifiedById, t.IsDeleted, t.Id, t.CreatedDate, t.CreatedById, t.Active__c , ignore_maxid__c
From Twitter_Search__c t Where Id =:tsId

16:55:0.212|SOQL_EXECUTE_END|[169,44]|Rows:1
16:55:0.215|SOQL_EXECUTE_BEGIN|[27,34]|Aggregations:0|select id, name from Account where name = :Label.TWITTER_ACCOUNT_NAME
16:55:0.286|SOQL_EXECUTE_END|[27,34]|Rows:1
16:55:0.287|SOQL_EXECUTE_BEGIN|[60,21]|Aggregations:0|Select Name, Id, OwnerId, Username__c, Unknown_Twitter_Usernames__c, Password__c, Twitter_Max_Message__c,
Enable_Auto_Case_Creation__c, Bit_ly_Username__c, Bit_ly_Password__c, Twitter_Max_Twitter__c,
associate_DM__c, associate_cases_same_username__c, closed_case_duration__c
From Twitter_Account__c LIMIT 1000
16:55:0.321|SOQL_EXECUTE_END|[60,21]|Rows:3
16:55:2.609|SOQL_EXECUTE_BEGIN|[399,20]|Aggregations:0|select id, twitter_username__c from Contact where twitter_username__c in :twitterUserNames LIMIT 1000
16:55:2.663|SOQL_EXECUTE_END|[399,20]|Rows:0
16:55:2.663|SOQL_EXECUTE_BEGIN|[402,17]|Aggregations:0|select id, twitter_username__c from Lead where IsConverted = false and twitter_username__c in :twitterUserNames LIMIT 1000
16:55:2.721|SOQL_EXECUTE_END|[402,17]|Rows:0
16:55:2.724|SOQL_EXECUTE_BEGIN|[197,41]|Aggregations:0|select Case__c, Contact__c, twitterid__c, type__c from Twitter_Conversation__c where twitterid__c in :twitterIds LIMIT 1000
16:55:2.736|SOQL_EXECUTE_END|[197,41]|Rows:0
16:55:2.737|SOQL_EXECUTE_BEGIN|[201,41]|Aggregations:0|select Case__c, Contact__c, twitterid__c, type__c from Twitter_Conversation__c where twitterid__c in :twitterIdsExist LIMIT 1000
16:55:2.772|SOQL_EXECUTE_END|[201,41]|Rows:0
16:55:2.891|DML_BEGIN|[1676,3]|Op:Upsert|Type:sf4twitter__Twitter_Conversation__c|Rows:60
16:55:3.97|ENTERING_MANAGED_PKG|sf4twitter
16:55:3.100|CUMULATIVE_LIMIT_USAGE
16:55:3.100|CUMULATIVE_LIMIT_USAGE_END

16:55:3.410|ENTERING_MANAGED_PKG|sf4twitter
16:55:3.414|SOQL_EXECUTE_BEGIN|[22,54]|Aggregations:0|select id, name, Twitter_Bio__c, twitter_creation_date__c,
twitter_follower_count__c, twitter_following_count__c, twitter_location__c,
twitter_status_count__c, twitter_last_tweet__c
from Contact where id in :contactIds
16:55:3.417|SOQL_EXECUTE_END|[22,54]|Rows:0
16:55:3.418|SOQL_EXECUTE_BEGIN|[26,45]|Aggregations:0|select id, name, Twitter_Bio__c, twitter_creation_date__c,
twitter_follower_count__c, twitter_following_count__c, twitter_location__c,
twitter_status_count__c, twitter_last_tweet__c
from Lead where id in :leadIds and IsConverted = false
16:55:3.420|SOQL_EXECUTE_END|[26,45]|Rows:0
16:55:3.423|CUMULATIVE_LIMIT_USAGE
16:55:3.423|CUMULATIVE_LIMIT_USAGE_END

16:55:3.428|DML_END|[1676,3]
16:55:3.430|METHOD_EXIT|[15,23]|sf4twitter.AutomationWrapper.doSearchKeyword(Id, Integer)
16:55:3.430|METHOD_ENTRY|[16,14]|system.debug(String)
16:55:3.430|USER_DEBUG|[16,14]|DEBUG|result for Search - WorldCup: <?xml version="1.0" encoding="UTF-8"?><result><conversations>60</conversations><cases>0</cases><caseComments>0</caseComments><contacts>0</contacts><leads>0</leads><errorCode>2</errorCode><errorMsg>null</errorMsg><pageNumber>2</pageNumber></result>
16:55:3.430|METHOD_EXIT|[16,14]|system.debug(String)
16:55:3.430|METHOD_ENTRY|[23,29]|String.indexOf(String, Integer)
16:55:3.430|METHOD_EXIT|[23,29]|String.indexOf(String, Integer)
16:55:3.430|METHOD_ENTRY|[25,34]|integer.valueof(String)
16:55:3.430|METHOD_ENTRY|[25,50]|String.substring(Integer, Integer)
16:55:3.430|METHOD_ENTRY|[25,62]|String.indexOf(String, Integer)
16:55:3.430|METHOD_EXIT|[25,62]|String.indexOf(String, Integer)
16:55:3.430|METHOD_ENTRY|[25,96]|String.indexOf(String, Integer)
16:55:3.430|METHOD_EXIT|[25,96]|String.indexOf(String, Integer)
16:55:3.430|METHOD_EXIT|[25,50]|String.substring(Integer, Integer)
16:55:3.430|METHOD_EXIT|[25,34]|integer.valueof(String)
16:55:3.430|METHOD_ENTRY|[26,17]|system.debug(String)
16:55:3.430|USER_DEBUG|[26,17]|DEBUG|pageNo : 2
16:55:3.430|METHOD_EXIT|[26,17]|system.debug(String)
16:55:3.430|METHOD_ENTRY|[29,35]|01p900000004nXS|sf4twitter.AutomationWrapper.doSearchKeyword(Id, Integer)
16:55:3.430|ENTERING_MANAGED_PKG|sf4twitter
16:55:3.431|SOQL_EXECUTE_BEGIN|[169,44]|Aggregations:0|
Select t.Weight__c, t.Unknown_Twitter_Usernames__c, t.Twitter_Max_Search__c,
t.Twitter_Keyword_Search__c, t.SystemModstamp, t.OwnerId, t.Name, t.LastModifiedDate,
t.LastModifiedById, t.IsDeleted, t.Id, t.CreatedDate, t.CreatedById, t.Active__c , ignore_maxid__c
From Twitter_Search__c t Where Id =:tsId

16:55:3.436|SOQL_EXECUTE_END|[169,44]|Rows:1
16:55:3.439|SOQL_EXECUTE_BEGIN|[60,21]|Aggregations:0|Select Name, Id, OwnerId, Username__c, Unknown_Twitter_Usernames__c, Password__c, Twitter_Max_Message__c,
Enable_Auto_Case_Creation__c, Bit_ly_Username__c, Bit_ly_Password__c, Twitter_Max_Twitter__c,
associate_DM__c, associate_cases_same_username__c, closed_case_duration__c
From Twitter_Account__c LIMIT 1000
16:55:3.443|SOQL_EXECUTE_END|[60,21]|Rows:3
16:55:3.446|SOQL_EXECUTE_BEGIN|[399,20]|Aggregations:0|select id, twitter_username__c from Contact where twitter_username__c in :twitterUserNames LIMIT 1000
16:55:3.448|SOQL_EXECUTE_END|[399,20]|Rows:0
16:55:3.448|SOQL_EXECUTE_BEGIN|[402,17]|Aggregations:0|select id, twitter_username__c from Lead where IsConverted = false and twitter_username__c in :twitterUserNames LIMIT 1000
16:55:3.450|SOQL_EXECUTE_END|[402,17]|Rows:0
16:55:3.450|SOQL_EXECUTE_BEGIN|[197,41]|Aggregations:0|select Case__c, Contact__c, twitterid__c, type__c from Twitter_Conversation__c where twitterid__c in :twitterIds LIMIT 1000
16:55:3.452|SOQL_EXECUTE_END|[197,41]|Rows:0
16:55:3.452|SOQL_EXECUTE_BEGIN|[201,41]|Aggregations:0|select Case__c, Contact__c, twitterid__c, type__c from Twitter_Conversation__c where twitterid__c in :twitterIdsExist LIMIT 1000
16:55:3.454|SOQL_EXECUTE_END|[201,41]|Rows:0
16:55:3.455|SOQL_EXECUTE_BEGIN|[451,34]|Aggregations:0|select TwitterID__c, Twitter_Search__c,type__c from Twitter_Conversation__c
where Type__c = :Label.TWITTER_TYPE_SEARCH and Download_Name__c = :userId and Twitter_Search__c in :searches.keySet()
order by TwitterID__c desc limit 1
16:55:3.468|SOQL_EXECUTE_END|[451,34]|Rows:1
16:55:3.468|DML_BEGIN|[463,3]|Op:Update|Type:sf4twitter__Twitter_Search__c|Rows:1
16:55:3.483|ENTERING_MANAGED_PKG|sf4twitter
16:55:3.484|CUMULATIVE_LIMIT_USAGE
16:55:3.484|CUMULATIVE_LIMIT_USAGE_END

16:55:3.500|DML_END|[463,3]
16:55:3.500|METHOD_EXIT|[29,35]|sf4twitter.AutomationWrapper.doSearchKeyword(Id, Integer)
16:55:3.500|METHOD_ENTRY|[30,17]|system.debug(String)
16:55:3.500|USER_DEBUG|[30,17]|DEBUG|result for SubPages for WorldCupfor Page: 2: <?xml version="1.0" encoding="UTF-8"?><result><conversations>0</conversations><cases>0</cases><caseComments>0</caseComments><contacts>0</contacts><leads>0</leads><errorCode>2</errorCode><errorMsg>You have uncommitted work pending. Please commit or rollback before calling out</errorMsg><pageNumber>0</pageNumber></result>
16:55:3.500|METHOD_EXIT|[30,17]|system.debug(String)
16:55:3.500|METHOD_ENTRY|[32,26]|integer.valueof(String)
16:55:3.501|METHOD_ENTRY|[32,42]|String.substring(Integer, Integer)
16:55:3.501|METHOD_ENTRY|[32,61]|String.indexOf(String, Integer)
16:55:3.501|METHOD_EXIT|[32,61]|String.indexOf(String, Integer)
16:55:3.501|METHOD_ENTRY|[32,102]|String.indexOf(String, Integer)
16:55:3.501|METHOD_EXIT|[32,102]|String.indexOf(String, Integer)
16:55:3.501|METHOD_EXIT|[32,42]|String.substring(Integer, Integer)
16:55:3.501|METHOD_EXIT|[32,26]|integer.valueof(String)
16:55:3.501|METHOD_ENTRY|[33,17]|system.debug(String)
16:55:3.501|USER_DEBUG|[33,17]|DEBUG|pageNo for subpages returned: 0
16:55:3.501|METHOD_EXIT|[33,17]|system.debug(String)
16:55:3.501|CUMULATIVE_LIMIT_USAGE
16:55:3.501|LIMIT_USAGE_FOR_NS|(default)|
Number of SOQL queries: 1 out of 100
Number of query rows: 1 out of 10000
Number of SOSL queries: 0 out of 20
Number of DML statements: 0 out of 100
Number of DML rows: 0 out of 10000
Number of script statements: 10 out of 200000
Maximum heap size: 0 out of 3000000
Number of callouts: 0 out of 10
Number of Email Invocations: 0 out of 10
Number of fields describes: 0 out of 10
Number of record type describes: 0 out of 10
Number of child relationships describes: 0 out of 10
Number of picklist describes: 0 out of 10
Number of future calls: 0 out of 10
Number of find similar calls: 0 out of 10
Number of System.runAs() invocations: 0 out of 20

16:55:3.501|LIMIT_USAGE_FOR_NS|sf4twitter|
Number of SOQL queries: 16 out of 100
Number of query rows: 10 out of 10000
Number of SOSL queries: 0 out of 20
Number of DML statements: 2 out of 100
Number of DML rows: 61 out of 10000
Number of script statements: 38481 out of 200000
Maximum heap size: 231201 out of 3000000
Number of callouts: 1 out of 10
Number of Email Invocations: 0 out of 10
Number of fields describes: 0 out of 10
Number of record type describes: 0 out of 10
Number of child relationships describes: 0 out of 10
Number of picklist describes: 0 out of 10
Number of future calls: 0 out of 10
Number of find similar calls: 0 out of 10
Number of System.runAs() invocations: 0 out of 20

16:55:3.501|CUMULATIVE_LIMIT_USAGE_END

16:55:3.501|CODE_UNIT_FINISHED|SynchTwitterSearchWorldCup.doSynch
16:55:3.501|EXECUTION_FINISHED
paul-lmipaul-lmi

I'm not sure on the pagination.  This is my class (it's an account-based one, not search-based, but I presume the underlying Twitter integration code is the same).

 

global class SynchTwitter Implements Schedulable{
  global void Execute(SchedulableContext SC){
    doSynch();
  }
  
  @future (callout=true)
  static void doSynch(){
    sf4twitter.automationwrapper aw; 
    sf4twitter__twitter_account__c acc = [select id from sf4twitter__twitter_account__c where name = 'logmeinhelp' limit 1];
    string s = sf4twitter.automationwrapper.doSearchAccount(acc.id,0); 
    system.debug('result: ' + s);    
  }
}

 

From what I understand, the error you're getting is due to try ing to make a callout when you have an SObject that has been updated in memory, but not committed to the DB.  I'm not too sure how to approach that issue, since you don't have access to the Twitter class itself to confirm it's inserting the SObject after each page.  I will note, that theoretically, this will fail after the 10th page though, since you can only do 10 callouts per execution.

ContinousImprovementContinousImprovement

Thanks Paul for the information.