31

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(...


26

Yes, queueable methods can run in parallel. As a proof of concept, here's some code that I wrote: public class TenSecondQueueable implements Queueable { public void execute(QueueableContext context) { System.debug(LoggingLevel.ERROR, DateTime.now()); Long start = DateTime.now().getTime(); while(DateTime.now().getTime()-start<...


23

The next lines on salesforce documentation about Queueable interface say the following You can’t chain queueable jobs in an Apex test. Doing so results in an error. To avoid getting an error, you can check if Apex is running in test context by calling Test.isRunningTest() before chaining jobs. So to test funcionality you can simulate chaining: ...


14

Since you are calling the first queable from a trigger and the limit shows Number of queueable jobs added to the queue: 1 out of 1 I believe what is happening is You save a record and the trigger runs. It enqueues your first job. The first job runs. The //do stuff (At line 1 in code below) performs a DML or a workflow update is triggered which causes the ...


13

Transactions have to be fully ACID compliant. The "C" stands for consistency, and this is where transaction control comes in. In order for your Queueable to execute, it has to be guaranteed that the transaction that placed the Queueable into the queue has committed. This means that your Queueable cannot run before the transaction has been fully committed to ...


13

sObjects (and other objects, for that matter) that are instance variables in Queueables and in Batch Apex classes are serialized and stored, and then deserialized at the time the Asynchronous Apex is executed. Field values for sObjects are not refreshed unless your code performs an explicit SOQL query to do so. Take this Queueable, for example: public ...


11

As Dan Appleman notes in the latest edition of Advanced Apex, a Queueable can call a Future method, and a Future method can enqueue a Queueable job. This works in Spring 16, and will allow chaining of an unlimited number of Queueable jobs, regardless of whether they do a callout or not. public without sharing class thisQueueable implements Queueable, ...


10

Wasted about 2 months to get an answer from salesforce support why I get Too many queueable jobs added to the queue: 2 when documentation (https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_queueing_jobs.htm) says that the limit is 50 for entry point? The root cause was in the undocumented limit for invocation of System....


9

That's an interesting question. With the queueable execution being asynchronous, could there be a particular timing where the queued job would start executing before the corresponding Callout__c record is inserted in the transaction that queued the job? My understanding is that the job isn't actually enqueued ready for execution until the DML operations ...


9

Spring '16 brings us a new method: System.isQueueable() which takes care of this requirement. releasenotes.salesforce.com/en-us/spring16/release-notes/rn_apex_new_classes_methods.htm As of Spring '16, isBatch() does NOT return true from inside Queueable implementation.


9

The other alternative is to not use Queueable for that purpose. I actually wrote a very fancy Batchable class that did something like that. One interesting design pattern is to make a batch action buffer. It basically looks like this: global class ChainBatch implements Database.Batchable<BatchAction>, Database.AllowsCallouts, Database.Stateful, ...


9

This pattern is likely to cause tricky-to-debug issues in the future. When your trigger is invoked via updates made in a Batch Apex class, you will get an exception stating that you've enqueued too many jobs at 2. Too many queueable jobs added to the queue: 2 As you may know, the limit per transaction is 50 (so if you're enqueuing five Queueables per ...


8

There are really two questions here: chaining and order guarantee. Chaining is possible by calling System.enqueueJob while inside the execute(Queueable) method, but the documentation also states that you can't chain inside a test method (for Queueable or Batchable interfaces). There is a current limit of 2, to prevent runaway queueable code, although the ...


8

Spring '17 provides: Make Web Service Callouts from Chained Queueable Jobs Apex now allows web service callouts from chained queueable jobs. Previously, a queueable job could make a web service callout, but additional chained jobs that made callouts would throw exceptions. See Also: Idea Exchange: Allow Callouts from Chained Queueable Apex Jobs


8

There is an Idea out there called Allow callouts from chained queueable Apex jobs. Here's the description, with some minor reformatting: Allow callouts from chained queueable Apex jobs Currently (Spring '15 release) callouts are not allowed from chained queueable jobs. The intial queable job will perform the web callout but any subsequent jobs that are ...


8

Yes, the documentation in question is incorrect. You can prove that the Limits class does not conform to what is written therein fairly easily: public class Demo implements Queueable { public void execute(QueueableContext context) { system.assertEquals(1, Limits.getLimitQueueableJobs()); } @future public static void doStuff() {...


8

The most important difference would be that constructor is executed in current execution context, and execute method is executed in new one. In practice it mean that if you call your queueable in trigger or after DML -- it would not be possible to make callout in constructor, but only in execute method.


7

This is one of those situations where you have to cheat to get perfect coverage. What you need to do is call your queueable's execute method without actually using the queueing mechanism-- then, the recursive call will fire appropriately, allowing you to get that perfect coverage. Something like this: // Do whatever initialization you need. Test.startTest()...


7

It's a powerful pattern, and when leveraged properly opens up a completely different programming paradigm. We've used this to do a lot of heavy lifting in consulting, and also to allow different packages to communicate with each other using domain events as glue between services.               ...


7

Remove the transient keyword. It causes the variable not to get serialized. Using the transient Keyword Use the transient keyword to declare instance variables that can't be saved, and shouldn't be transmitted as part of the view state for a Visualforce page. For example: Transient Integer currentTotal; You can also use the transient keyword in Apex ...


7

Tl;dr: I don't recommend using a constructor like this. I think this would violate the principle of least astonishment in a few ways: Constructor has logic in it (when they're normally used to populate class variables and such) The execute() method doesn't contain the logic that's executed While the effect is likely to be the same, putting your logic in ...


6

You forgot to tell the system that the Queueable class allows callouts. The documentation doesn't really call this out, but you need to use Database.AllowsCallouts, like so: public class vNImageOptimizationJob implements Queueable, Database.AllowsCallouts { // ... } This is the same limitation that Database.Batchable imposes. There's no need to make your ...


6

See Queueable Apex (emphasis mine): Chaining Jobs If you need to run a job after some other processing is done first by another job, you can chain queueable jobs. To chain a job to another job, submit the second job from the execute() method of your queueable class. You can add only one job from an executing job, which means that only one child job can ...


6

According to the Apex Developer Guide documentation on Queueable Apex, there is no depth limit in most org types. The following should probably be amended to include sandbox organizations: No limit is enforced on the depth of chained jobs, which means that you can chain one job to another job and repeat this process with each new child job to link it ...


6

When you need more than one execution, but you want to test the asynchronous code independently, you can cheat by rolling them back. Here's an example in a unit test: Test.startTest(); SavePoint sp = Database.setSavePoint(); // Replace this with real code executeTheTrigger(); // Do any asserts, etc... // Roll back the transaction Database.rollback(sp); ...


6

I would say, the constructor is best used just as "prep". The work you want to enqueue should be done in the execute method. You always have the option, when constructing a Queueable, to run the work synchronously by calling the execute method. E.g. I have used this pattern so I can decide based on limits or recursion whether to do the work right now or ...


5

This is broad questions but let me try to give you summery 1) You can pass Array of objects to Queueable in future you can not. 2) You can chain jobs in Queueable in future you can not. Ex. You are calling API X and on success you are calling API Y with result of first call(X) this you can do easily in Queueable 3) Queueable is seen as combination ...


5

If your class specifies "with sharing", it runs in user context. Otherwise, it should run in system context. You may want to use "without sharing" to make sure it runs in system context.


5

You're correct, performing your DML operations inside a Queueable execution is a separate transaction so you will have a fresh set of governor limits.


5

I thought it'd be good to share my solution with you. I ended up contacting Salesforce support and after some messages back and forth it turned out that there's some sort of backend setting that needs switched on: Tier 3 has enabled the permission "Apex queueable" in this Org. Now, you should be able to implement queueable interface. Maybe someone ...


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