3

Recently I was working on a project where, in order to deal with recursion and governor limits, the previous developer decided to send Platform Events, with the expectation that the very same Salesforce org would catch and handle the event.

This was evidently working in production (at least sometimes), but the test classes -- even though they contained Test.stopTest() -- suffered intermittent failures.

This was out of scope for my activities, so I didn't dig too deep into it (and I can't share any code, sorry), but I am wondering:

  1. Since Platform Event were not designed as an asynchronous solution, is it reliable within a test context to assume that both their being published and handled should be triggered and completed by Test.stopTest()?

  2. The idea, as I understand it, of the publisher/subscriber model is that the published shouldn't have to know or care whether there are any subscribers, whether they catch the message, or what (if anything) they do with those messages. This being the case, is it reasonable to expect or to code as if a Salesforce org will catch all the events it generates?

  3. If there are no subscribers outside the Salesforce org, are there any good use cases where Platform Events should (or must) be used instead of Batchables, Queueables, and/or Future methods?

2 Answers 2

4

Since Platform Event were not designed as an asynchronous solution, is it reliable within a test context to assume that both their being published and handled should be triggered and completed by Test.stopTest()?

They should be considered reliable for production code, but there's no guarantee they'll work correctly in unit tests. In fact, at one point, PE would leak test data to the production database. They have fixed this since, but PEs are still relatively new and may be glitchy during unit tests.

The idea, as I understand it, of the publisher/subscriber model is that the published shouldn't have to know or care whether there are any subscribers, whether they catch the message, or what (if anything) they do with those messages. This being the case, is it reasonable to expect or to code as if a Salesforce org will catch all the events it generates?

Yes, it should work as expected, and there's even a retry mechanism in case those triggers fail. It's a fairly robust system for production data, although, again, you can't precisely rely on them during unit tests.

If there are no subscribers outside the Salesforce org, are there any good use cases where Platform Events should (or must) be used instead of Batchables, Queueables, and/or Future methods?

The main problem with Batchable, Queueable, and Future methods is that they can all be canceled. For example, consider the following code:

Savepoint sp = Database.setSavePoint();
Database.insert(records, false);
SomeClass.futureMethod();
Database.rollback(sp);

In this case, the futureMethod will never be called when those records that were inserted are rolled back. With EventBus.publish, those events will be dispatched, even if you later roll back the transaction. The primary use for intra-org communication seems to be that you can log fatal errors, and they'll be processed even if the transaction that published them rolls back later. This can be useful for logging data that will need to ultimately survive the cancellation of the parent transaction. Admittedly, most developers never use it for this purpose, but it's useful to know this feature exists.

2
  1. It is really hard to debug for possible causes of the events not being delivered as a part of the test. There are quite a few nuances of testing with platform events. The official reference can be found here, https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_event_apex_tests.htm. You can use Test Deliver to validate the processing of event on delivery. https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_test_deliver.htm

  2. Salesforce guarantees at least once delivery of the events. I am yet to observe a scenario where the events were lost in the very limited experience I have had with them. If the same salesforce org has a listener/trigger for those platform events, you should expect, it to be triggered for every event.

  3. On this point a very good discussion can be found here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .