top of page
Search
  • Writer's pictureAvi Rai

Go asynchronous with Platform Events

Updated: Aug 29, 2021

What are Platform Events?


Platform events are the event messages (or notifications) that your apps send and receive to take further action. They simplify the process of communicating changes and responding to them. They are based on event-driven (or message-driven) software architecture which consists of event producers, event consumers, and channels.


Use Platform Events to execute code asynchronously


Platform Events can be used to execute the code asynchronously. Let's see how, the first step is to publish Platform Event(s) wherever we want some code to run in the background. Then simply have a trigger that listens to the event(s) and contains the background process to run. That's it!

We can also add information in the fields of Platform Event while publishing which can be consumed in the trigger for further processing. This trigger runs in a completely different execution context and thus overcomes the governor limits. This process gives results faster than any usual asynchronous operations (Queue, Future, Batch) as Platform Events do not get queued, they execute immediately as soon as published. We call this process asynchronous because it runs in a different execution context than the actual code publishing events but it runs with synchronous governor limits.


Cool features:

  1. Resume a Platform Event Trigger After an Uncaught Exception.

  2. Retry Event Triggers with EventBus.RetryableException. You can run a trigger up to 10 times when it is retried (the initial run plus nine retries)

  3. The maximum batch size of a platform event trigger is 2,000, while the maximum of an Apex object trigger is 200.

  4. We can control the platform event trigger batch size and it can be different for different batches.

A small example, where I am creating a Task record for all leads present in my org. Firstly in CreateTaskForLeads, I am querying the leads where one field Follow_Up_Date__c is in the future and publishing the Platform Events.

public with sharing class CreateTaskForLeads {
    public static void createTasks(){
        List<CreateTaskEvent__e> events = new List<CreateTaskEvent__e>();
        for(Lead lead :[SELECT Id FROM Lead WHERE Follow_Up_Date__c >= TODAY]) {
            CreateTaskEvent__e evt = new CreateTaskEvent__e();
            evt.Record_Id__c = lead.Id;
            events.add(evt);
        }
        Eventbus.publish(events);
    }
}

A simple trigger on Platform Event CreateTaskEvent__e

trigger CreateTaskEventTrigger on CreateTaskEvent__e (after insert) {
    CreateTaskEventHandler.createTasks(Trigger.New);
}

The trigger handler which is creating tasks

public with sharing class CreateTaskEventHandler {
    public static void createTasks(List<CreateTaskEvent__e> changeEvents){
        Set<Id> leadIds = new Set<Id>();
        for(CreateTaskEvent__e evt : changeEvents) {
            leadIds.add(evt.Record_Id__c);
        }
        Map<Id,Lead> leads = new Map<Id,Lead>([SELECT Id,Name,
                                               OwnerId,Follow_Up_Date__c FROM Lead WHERE Id IN :leadIds]);

        List<Task> taskListToInsert = new List<Task>();
        Integer counter = 0;

        for(CreateTaskEvent__e evt : changeEvents) {
            counter++;
            // I am breaking the loop when 100 records are processed in current batch
            // thus remaining records will be part of next batch
            // "Remember by default the platform event trigger size is 2000"
            if(counter > 100) {
                break;
            }
            
            // Get lead record
            Lead l = leads.get(evt.Record_Id__c);
            //Create Task
            Task newTask = new Task();
            newTask.WhoId = l.Id;
            newTask.OwnerId = l.OwnerId;
            newTask.ActivityDate = l.Follow_Up_Date__c;
            newTask.Subject = 'Follow Up ' + l.Name;
            taskListToInsert.add(newTask);

            // Setting resume checkpoint, in case exception occurs or
            // we want to break execution then remaning events will be 
            // considered in next batch
            EventBus.TriggerContext.currentContext().setResumeCheckpoint(
                evt.ReplayId);
        }

        try{
            insert taskListToInsert;
        } catch(Exception e) {
            // Throwing EventBus.RetryableException if any error occurs
            // Also performing retries 6 times
            // "Remember you can run a trigger up to 10 times when it is retried (the initial run plus nine retries)"
            if(EventBus.TriggerContext.currentContext().retries < 6) {
                throw new EventBus.RetryableException(
                            e.getMessage());
            }
        }        
    }
}



Thanks for reading. Welcome all views/opinions/suggestions and hope you liked it.

Stay safe and healthy :)

2,788 views0 comments

Recent Posts

See All

What is Modal? A modal overlays a popup on top of the current app window. This paradigm is used in cases such as the creation or editing of a record, as well as various types of messaging and wizards.

Hello everyone, We know that there are two methods to call an Apex method from a Lightning Web Component: Wire Apex Methods to Lightning Web Components Call Apex Methods Imperatively When calling apex

Post: Blog2_Post
bottom of page