4

This is a general design question on how to structure trigger files for platform events. Say I publish a platform event "lead created" and I want to do several distinct things within the same Salesforce org that published the event. I know the way that Salesforce "subscribes" to this event is via a trigger on the pEvt. I'm thinking the design should be multiple trigger files (one for each "subscriber") when processing the event via apex instead of the "one trigger per object" rule with custom objects. The thinking is that each trigger file is actually a distinct subscriber to the event and so should be separated out appropriately. This also means logic would be written within the trigger, which should be fine since the only phase that is supported is 'after insert'. Most trigger frameworks take care of working with the different phases which doesn't apply to pEvts.

I'd like to know if this design makes sense and if anyone else has implemented a platform event design where the "subscribers" are actually within the same Salesforce org that published the event.

4

This is interesting, I quickly wrote 2 triggers on a platform event. And when I fired them I could see 2 debug logs, saying both triggers were own transaction.

Both being own transaction means, they get own set of limits. Also as both are the async process you genuinely don't care about the order of execution.

I have made architecture where we split our process via events and subscribe via triggers, but never tried something like having 2 triggers on 1 event.

I believe you can do this when you wanna make a couple of complicated processes independent of each other. Having multiple subscribers to same event do makes sense in my opinion.

  • 2
    if each trigger is its own execution context, that makes a great case to have each "subscriber" separated out into its own trigger. – willard Jul 2 at 15:59
3

This is all rather subjective. However, some comments from my perspective:

  1. For testability, without the need to actually insert data into the database (for traditional triggers) or actually publishing events on the event bus (for platform events), IMHO you should always put all the trigger code into a separately testable Apex class, simply calling that code as a one-liner trigger. This has multiple benefits, and these are my top 2:

    1.a. This makes your tests run faster (no need to insert into the DB through either mechanism)

    1.b. You can use a "factory method with dependency injection" approach (see this previous answer for a description of that pattern) to allow mocking out trigger behaviour in "integration type unit tests"

  2. It makes logical sense to me, in terms of design best practice, to split out the subscribers - after all, order of execution is very unlikely to be relevant between the subscribers as you have implied. You do, however, want to check to see if there are any limits that might get in the way of this approach.

  3. We have implemented an Apex-based subscriber for our own Platform Event in our managed package. The reason we did this was two-fold:

    3.a. The Platform Events are processed in a separate and asynchronous manner, regardless of what happens in the initiating session

    3.b. The trigger is executed as a different user (the Automated Process user) than the contextual user where the event was published.

  4. We used the "factory method with dependency injection" approach, and unit tests for our event subscriber code that don't actually rely on the publishing of events.

1

In addition to the other answers:

Once you go the multiple triggers per xxx__e approach you need to consider race conditions and record locking in your design. There is no guarantee of which trigger will execute "first" and furthermore, Trigger t might get X records per transaction and Trigger u might get Y (X notequal Y) records per transaction. Both triggers can execute concurrently.

It may also complicate any error retry use cases where the xxx__e event on Trigger t passes whereas Trigger u fails.

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.