The Stack Overflow podcast is back! Listen to an interview with our new CEO.

Hot answers tagged

29

(1) To determine the number of Future calls run in the past 24 hours, you can use this utility method: public static Integer GetNumFutureCallsInLast24Hours() { return [select count() from AsyncApexJob where CreatedDate >= :Datetime.now().addHours(-24) and JobType = 'Future']; (2) To dynamically run methods in a future ...


26

Yes, Queueable can be called from Database.Batchable classes. You must go through enqueueJob for this to work: public class BatchClass implements Database.Batchable<SObject> { public Database.QueryLocator start(Database.BatchableContext context) { return Database.getQueryLocator([SELECT Id FROM Account]); } public void execute(...


23

Yes! I love this question, as it's one of my pet peeves. People don't test @future calling methods because they don't know it's possible. Enter the magic of two key methods: Test.StartTest(); Test.StopTest(); When you utilize these methods -- and you should! they do a couple of key things for you. they reset your governor limits so you can test if your ...


20

Your logic is slightly flawed. All async code can run in to stale data. The difference between Batchable, Queueable, and Future methods is how they're designed to behave. Batchable calls were designed to allow for heavy asynchronous processing. But, it was the only asynchronous code at one point, and it was too "heavy" in terms of resource usage, and had a ...


19

Create a batchable class, and do as many callouts as you need. The 100 callout limit applies only to a single transaction, but Batchable classes can create millions of transactions. There's plenty of examples on the forum here already about how batchable works, but for sake of argument, say you wanted a quick-and-dirty way to get started, you could do this: ...


18

I guess the answer is the SF document itself. Have a look at this link http://www.salesforce.com/us/developer/docs/pages/Content/pages_js_remoting.htm You can configure your remoting call using these three parameters "buffer","timeout" and "escape". Usually written at the end of a call. You have to look for the parameter "buffer". As per the docs buffer ...


18

The error is straightforward. To work around it, you need to detect when you're already in an @future or batch context, and then simply not call your @future method(s). Dan Appleman has a pretty good pattern for this, which he presented at one of his sessions at Dreamforce this year. Defensive Apex Programming Slides 8-10 are the relevant ones here. For ...


17

@Future's are queued transactionally along with other db changes in the trigger transaction, so the future can't be executed until the enqueuing transaction commits. (and conversely, if the trigger transaction never commits due to errors etc, the @future is never executed)


17

UPDATED ANSWER (not batch but...). I was investigating the ScheduledDispatcher: https://gist.github.com/gbutt/11151983 And lo and behold this works: global class ScheduledDispatcher Implements Schedulable{ public Interface IScheduleDispached{ void execute(SchedulableContext sc); } global void execute(SchedulableContext sc){ ...


17

Great question, the correct place to make callouts to synchronise with external systems is not initially that obvious, especially when there are so many ways in which users and/or developers can create data within Salesforce, such as Salesforce API's, Apex DML and Standard UI, you need to be sure to capture all these places or risk gaps in your external ...


17

The method looks like this: static public Boolean isFutureRunning(System.Type type, String methodName) { String namespacePrefix; String name; if (type.getName().contains('.')) { //managed (namespaceprefix.classname) namespacePrefix = type.getName().substringBefore('.'); name = type.getName().substringAfter('.'); } ...


17

While a @future method cannot call another, it can execute a Queueable. Here is some documentation. They might even be more useful than @future methods for both operations, as they can be chained.


17

It sounds like a bug, or at least it is not documented; I would not depend on this behavior. If you want to test asynchronous code, use Test.stopTest(). This applies for Schedulable, Queueable, Batchable, and @future methods. If you're not using Test.stopTest(), then you're obviously not checking the results of the execution, which means you're only writing ...


15

According to the documentation here: Methods with the future annotation must be static methods, and can only return a void type. The specified parameters must be primitive data types, arrays of primitive data types, or collections of primitive data types. Methods with the future annotation cannot take sObjects or objects as arguments. You'll have ...


13

A few thoughts: If you are dealing with a collection the string resulting from JSON serialization could become prohibitively large. This could result in heap size limit issues during deserialization. The data in the sObject may be stale by the time the future method executes. Fields may have been changed on the Contact before the future method runs. You may ...


13

There is an official explanation from Salesforce, Asynchronous Processing in Force.com http://www.salesforce.com/us/developer/docs/async_processing/salesforce_async_processing.pdf


13

Using System.enqueueJob, Database.executeBatch, System.scheduleBatch, System.enqueueJob, and @future methods all modify the state of the database, so for purposes of callouts, count as a DML operation. This also means that Database.rollback can undo a scheduled job, batch job, queueable, or future method. Also note that any of those methods will prevent you ...


12

When I've had need for this, I've always used the following pattern, which works out well: trigger X on Y (after insert, before update) { if(Trigger.isAfter && Trigger.isInsert) { update Trigger.new.deepClone(true, false, false); } if(Trigger.isBefore && Trigger.isUpdate) { for(Y record: Trigger.new) { ...


12

With the newly available Queueable interface this problem becomes more approachable. replace your @Future annotated method with a Queueable inner class lean on Limits.getQueueableJobs() to count the jobs before and after Example @IsTest public class QueueableTest { public class MyJob implements Queueable { public MyJob(String param1, String ...


11

Doh. I figured it out. I was being silly and including the describe operation inside my iteration loop. I only need to do that once since the object schema isn't going to change between objects. Fixed code below: trigger ObjectBefore on Object__c (before update) { Set<String> fieldsToIgnore = new Set<String> {'custom_field1__c', ...


11

The Limits class as you have started to discover is only for the current request and does not provide any org wide limit information. Salesforce have partially addressed this with emails, but as far as I can see there is nothing for Batch Apex or @future. Though I have included some thoughts below on both. Emails. There is a couple of methods on the ...


11

2999 is a lot of callouts to be making in one transaction. Is the user going to sit there and wait for them to finish? Brian's suggestion to use Batch Apex is a common way to deal will bulk callouts. It's definitely a good way to scale up the number of callouts that can be made. Being asynchronous is nature, the user won't have much feedback on how the ...


11

Basically, you need to know about how to test HTTP callouts, and how to test future methods. Once you've gotten that far, you'll see that the unit test would look like: @isTest class MakeCalloutTest { // Simple echo callout class // Returns whatever response we tell it to when asked class EchoHttpMock implements HttpCalloutMock { ...


10

Answer and Why. After spending some further time on this, I believe the answer to your question in determining if the future feature is available programatically is unfortunately, no this is not possible. I've considered the following in arriving at this answer for you. Catching the LimitException. This is unfortunately not possible. I have had luck in ...


10

I would take a look at Dan Appleman's DF13 Presentation here - he talks about these types of scenarios and how you can create Batch/Schedule Managers to achieve the type of continuous processing you are describing without hitting the Batch limits


10

The governor limit is that no more than 10 future calls may be made in a single request so your trigger is broken as soon as more than 10 Case objects are updated at once that match you if condition. If you want to use a future method call it once and pass it the set of case IDs i.e. collect the set if IDs first then make a single call to the future method. ...


10

This is a very common issue that one encounters The issue happens you are doing a DML before you do a Callout .To replicate this issue one can try things like Account acc=new Account(); acc.Name='Test exception'; insert acc;//insert a dummy account Http h = new Http();//DO a HTTP callout HttpRequest req = new HttpRequest(); req.setEndPoint(...


10

I've implemented the following in numerous orgs and it works pretty well. It's similar to Keith's suggestion, but a bit more detailed and it does usually do near-realtime processing: Create a custom object to queue records that need to be sent via callout. Each time a callout is required add a record, use an auto-number to preserve ordering Do all of your ...


9

You need to maintain schema in class as static collection(Map) and then refer that class in trigger. Refer following code - // Key : SobjectAPIName For ex. Account // Value : Map<String, Schema.SObjectField>, field map (k:fieldname, v:Schema.Sobjectfield) private static final Map<String, Map<String, Schema.SObjectField>> ...


9

My understanding is as follows - I can't remember where I heard/read this though, so caveat emptor: If you could pass an sObject as a parameter you would send the current record contents (fields) to the future method. As this executes asynchronously, the contents may be stale as field changes could be applied through triggers etc. Therefore the language "...


Only top voted, non community-wiki answers of a minimum length are eligible