Detecting Duplicate Queueable Jobs
Build a Queueable Signature
To create a unique queuable signature, first declare an instance of the AsyncOptions class. Then set the value of the instance’s DuplicateSignature property to a QueueableDuplicateSignature object, which is built using the inner QueueableDuplicateSignature.Builder class.
To build the queueable signature, add different strings, IDs, or integers using these methods from QueueableDuplicateSignature.Builder.
- addString(inputString)
- addId(inputId)
- addInteger(inputInteger)
As you build the signature, you can find the size, remaining size, and maximum size of the queueable job signature in bytes using these methods from the QueueableDuplicateSignature.Builder class.
- getSize()
- getRemainingSize()
- getMaxSize()
When the signature has the required components, call the .build() method and assign the signature to the DuplicateSignature property.
Enqueue a Job with a Queueable Signature
After you build a queuable signature, enqueue a new job using the System.enqueueJob(queueable, asyncOptions) method. Set the asyncOptions parameter to the AsyncOptions instance with the queueable signature that identifies the unique job. When the new job is enqueued, the system checks for existing enqueued jobs with the same signature. If other enqueued jobs with the same signature are found, then the enqueue operation for the new job fails, and a DuplicateMessageException is thrown.
However, if other jobs with the same signature are already running when the new job is enqueued, then the enqueue operation for the new job succeeds. Therefore, duplicates of already running jobs can still occur in this case. This behavior occurs because the queuable signature is removed from the job when it’s first dequeued, so a running job no longer has a signature. This removal guarantees that at least one job instance for a given signature runs.
Examples
This example builds the async job signature using the User Id and the string MyQueueable.
1AsyncOptions options = new AsyncOptions();
2options.DuplicateSignature = QueueableDuplicateSignature.Builder()
3 .addId(UserInfo.getUserId())
4 .addString('MyQueueable')
5 .build();
6try {
7 System.enqueueJob(new MyQueueable(), options);
8} catch (DuplicateMessageException ex) {
9 //Exception is thrown if there is already an enqueued job with the same
10 //signature
11 Assert.areEqual('Attempt to enqueue job with duplicate queueable signature',
12 ex.getMessage());
13}This example builds the async job signature using the ApexClass Id and the hash value of an sObject.
1AsyncOptions options = new AsyncOptions();
2options.DuplicateSignature = QueueableDuplicateSignature.Builder()
3 .addInteger(System.hashCode(someAccount))
4 .addId([SELECT Id FROM ApexClass
5 WHERE Name='MyQueueable'].Id)
6 .build();
7System.enqueueJob(new MyQueueable(), options);