11

I'm coming to a point where my software does to many things at the same time, so I decided to switch to Platform Events to decouple everything. I don't handle external events, I'm only planning to use it natively with apex.

Now I face some issues with a proper design behind it and wonder if anyone else already came up with something like best practices and/or platform specific requirements that could help me out here. Is there any Architectural Library to structure the Platform Event Trigger handling similar to how the fflib supports general Trigger handlers?

I couldn't find anything on google and the success community.

Things that aren't clear for me so far:

Several Events for everything?

  • Is it smart to create events like CaseInserted__e for all the possible objects i need to track, or is is smarter to have a general SObjectInserted__e event?
  • If so, I would have to handle them in a dispatcher-like triggerhandler, is that a good approach? Idk. both ways still seem like an overhead to me :(

Execution context and Limits

  • Are platform events a good approach to win the fight against limits?
  • If so, why are they coming in batches and not one by one? this confuses me the most :( Do I always have to consider my self if I need to split them or just publish the whole batch of events?
  • If I decide to use the events to decouple the code base, what kind of things should be done in regular triggers and what am I supposed to do in the events triggers?
  • Will there even be a need of regular triggers anymore, or should they be replaced, or just do simple stuff like updating fields?

So the main thing is, that I don't want to do too many wrong decissions right at the beginning and if there is any knowledge out there please share it :)

  • how did you end up designing your platform events? I'm thinking one trigger per subscriber, which would mean multiple triggers per event. Is this how you ended up doing things? salesforce.stackexchange.com/questions/267928/… – willard Jul 2 '19 at 14:13
  • Hi willard, I did decide against it back then and we are working with queueables most of the time. – Basti Jul 2 '19 at 14:31
7

Is it smart to create events like CaseInserted__e for all the possible objects i need to track, or is is smarter to have a general SObjectInserted__e event?

Generally, use one event for each unique type of event. Even though you're just using them in triggers right now, eventually you might decide to integrate with other systems, and they might only want some of the events (e.g. Cases but not Contacts). It's worth the time to split them up now.

If so, I would have to handle them in a dispatcher-like triggerhandler, is that a good approach? Idk. both ways still seem like an overhead to me :(

You can use an Apex Class to consolidate common code, and call them from each trigger. There's no need to write each trigger all over again and maintain separate copies of code.

Are platform events a good approach to win the fight against limits?

Yes, they can be used to combat limits, but please keep in mind that they cannot be rolled back. This means that if you fire off an event, and later use addError to prevent saving a record, you can't undo the event, so your trigger may operate erroneously.

If so, why are they coming in batches and not one by one? this confuses me the most :( Do I always have to consider my self if I need to split them or just publish the whole batch of events?

Triggers always execute in batches of 200 for efficiency. Just publish as many events as you need, the platform will take care of the rest for you. Executing one at a time would be a tremendous waste of resources; this was already learned the hard way in 2007 or so when they introduced Apex Code and Triggers. Back then, triggers only worked on one record at a time, and it caused mass updates to be incredibly inefficient.

If I decide to use the events to decouple the code base, what kind of things should be done in regular triggers and what am I supposed to do in the events triggers?

Validation and before-commit logic should happen in regular triggers for efficiency. Updating parent or child records can generally be done asynchronously, so they're the best candidates for platform events. However, complicated calculations that don't need to be done immediately could also be a candidate for Platform Events, even if it means you have to save over the same record more than once.

Will there even be a need of regular triggers anymore, or should they be replaced, or just do simple stuff like updating fields?

Anything that needs to happen in real time needs to be in the basic triggers, as mentioned above.

  • N.B. see also on the subject of triggers: salesforce.stackexchange.com/questions/215186/… which give additional reasons why separate xxx__e object types are useful to avoid limits issues – cropredy May 23 '18 at 16:07
  • Yeah.. Platform event trigger can have batch size more than 200, not sure why, – Pranay Jaiswal May 23 '18 at 17:35
  • Thank you fox! So in general you would support the idea to use them internally only? The rollback thing should be okay, as long as we keep the consequences in mind. We will probably use CometD and user feedback, to make it more reliable. @PranayJaiswal it's 2000 since they are supposed to be small messages instead of complex records. – Basti May 24 '18 at 7:52
  • 2
    @Basti I think I'd only use it if I had an intent to also deliver the messages to external systems. I'd prefer to use Queueable for day-to-day offloading of processing, because that's what it's designed for. A better use of Platform Events is for survivable error logging (because it can't be rolled back). It's a bit big to put in a comment, but you might want to consider using Queueable, and if you get stuck, ask some questions about how to avoid the problems of Queueable, instead. – sfdcfox May 24 '18 at 14:35
5

This post contains multiple questions and is probably too broad but let me try to answer anyway.

Overall I would say that using Platform Events (PEs) instead of triggers is not a good approach if you don't intend to integrate with external systems. PEs are meant to facilitate integration with external systems so you defeat its purposes by using it internally only.

PEs won't save you from limits because they are also limited (number of event types that you can declare, number of events that you can fire...).

Despite this, if you really want to use events to react to data changes, check out Change Data Capture. This is also meant for external integrations but it has the advantage of being built specially to track data changes while PEs are not.

  • Yaa I know :) It was just too many things that made me uncertain, if this even is the right use case.. Before my current situation, I used the exact same argument against PEs. But right now I don't see a better approach, to overcome the issues I have. It's just too many things that have to happen after one event. But it's nothing like processing some data, so I could use batches. Instead it's so many different things... Any idea if the Change Data Capture events will be accessible through apex? – Basti May 24 '18 at 9:10
  • Sorry, I have no clue about the CDC roadmap. – POZ May 28 '18 at 12:00
2

I haven't used them yet, but a couple of observations:

  1. DX and Platform Events look like a marriage made in heaven. Decoupling via events makes breaking up your system into feature packages much easier.
  2. Think hard about error handling and whether or not you may need to retry the events. This is what stops me. If my subscriber Apex fails to complete, how am I going to re-run it. How will the admin be able to monitor these failures? I've always used event-like custom objects instead. That way, the admin can build a report/dashboard. And set them to retry, if required.
  • Good to hear, that others thought of the same use case ;) You are right, the error handling is something, that we always need to keep in mind, while implementing these kind of event handlers. We are at least planning to provide feedback via the CometD api and maybe also provide "resolve" (rollback/re-run) actions with it. Additionally we will probably need more validation, before we publish these events, not sure yet, how to make them genereic and not coupled to the handlers... – Basti May 24 '18 at 7:56
1

Well you have to really ask what sort of problem you are solving.

The great thing about Platform Events over Queueables is that they guarantee the order of events, but only in certain cases. Publishing events to concurrent buses does not guarantee order: EventBus.publish(new event_A__e ( order__c = 1 )); EventBus.publish(new *event_B__e* ( order__c = 2 )); EventBus.publish(new event_A__e ( order__c = 3 )); Can arrive like 1,3,2 or 1,2,3 (but never 3,1,2 tho).

If you are looking into orchestrating asynchronous code, I highly recommend looking into Promise library (https://github.com/codefriar/promise). It utilises Queueables for it, which has somewhat higher limit.

Speaking of limits, Platform Events start at something like 100k per day, while async executions is 250k (which is still pretty low if you think about it).

  • 250K is minimum and if you have more licenses you get even more. – Pranay Jaiswal May 30 '18 at 8:51
  • That's 1250 licences which is a humongous org. – dzh May 30 '18 at 10:01
-2

@Basti Platform Events (PE) help you address the typical pitfalls of a request response communication model especially encountered during peer to peer integrations.

They help you implement a Publisher - Subscriber based event driven architecture thus avoiding the regular pitfalls encountered with point to point integration strategies such as 1. Wasted API calls resulting from periodic polling 2. Tight coupling between the producer and consumer in a message exchange

Also, one thing to note is that Platform Events are not a direct replacement for Synchronous Communication.

Several Events for everything?

As a best practice, if a communication process whether internal or external has too many steps to it, it is best to break them down and process them disparately rather than trying to accomplish everything one after another in a single execution context. This provides decoupling of responsibilities and promotes decoupling of entities involved in the message exchange.

Is it smart to create events like CaseInserted__e for all the possible objects i need to track, or is is smarter to have a general SObjectInserted__e event?

Ideally, Platform Events should be designed to handle event specific messages rather than generic ones. The reason for being so is, that every event should have message specific subscribers thus keeping the subscribers decoupled.

However, you can definitely identify certain common attributes which could be leveraged in more than one processes. For e.g. InvoicePaid could have Order details which could be leveraged for financial as well as for shipping & delivery. Hence, there has to be a significant design consideration put into defining the Platform Event schema to ensure that you create disparate events which can overlap across processes. The event payload should be more logical rather than an exact emulation of a Sobject.

Are platform events a good approach to win the fight against limits?

I would disagree to that since, although Platform Events promote a sense and respond based interaction between apps they have limits of their own. Some of the limits are

A general rule to designing applications for Force.com and avoid running into limits, is to move away from long running processes. Try to not to do too many things synchronously or you will encounter issues. Instead break each piece down and have that piece process synchronously if required.

If so, why are they coming in batches and not one by one? this confuses me the most :( Do I always have to consider my self if I need to split them or just publish the whole batch of events? Platform Events are published and made available in near real time which means they are processed in a different execution context and not in the same context as which the Database transactions occur. However, since that window of time, is relatively small and not necessarily as high as other async processing artefacts such as @future, Batch Jobs or Scheduled Jobs, Platform Events qualify and are limited by synchronous processing limits. Sounds wierd but true! Refer Platform Events & Transactions

If I decide to use the events to decouple the code base, what kind of things should be done in regular triggers and what am I supposed to do in the events triggers? Here are some of the considerations you should account for while writing triggers for Platform Events

  • PE triggers only execute on after insert
  • PE cannot be updated
  • Infinite Trigger loops and limits still apply hence you will need a mechanism to handle recursive execution of PE Triggers.
  • Record ownership needs to be set explicitly in PE Triggers. if you create a Salesforce record that contains an ownerId field, set the ownerId field explicitly to the appropriate user. Platform event triggers run under the Automated Process entity. If you don’t set the ownerId field on records that contain this field, the system sets the default value of Automated Process. This example explicitly populates the ownerId field for an opportunity with an ID obtained from another record.
  • EventBus.publish(List<Sobject>) counts against the Number of DML statement limits within that context.
  • Refer Considerations for Publishing / Subscribing to Platform Events using Apex & API
  • @basti If you intend to learn more about Platform Events and see what you can do with them, here is a link to my webinar - bit.ly/2IKxLVu This should give you a perspective. – Jigar Shah May 23 '18 at 23:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.