6

I am having few issues designing an architecture to use with Platform events and Microservices.

According to microservices principle(Kubernetes), there should be at least 3(odd number) services running so that it can handle the load properly. It works for callouts but for platform events it just gets bit tricky.

Here is our architecture :

Whenever some conditions, to send uploaded file to 3rd party for processing and get that data back in Salesforce. So flow goes like this

  1. Person X uploads a file(File can be big so can't do HTTP callouts to a 3rd party with file data)
  2. We fire a platform event with fileId(content version id)
  3. The 3rd party microservice listens to it and fetches that file from SF rest endpoint and then processes and updates its data back in SF

Now the problem is in microservice. There can be multiple instances of it listening and follows the independent processing architecture so that they can work without worrying what's going on in other instances.

So, in order to stop single point of failure there will be at least 3 services running,(Even more if peak load) and they listen to the same event and act independently. This is problematic as all 3(or evn more) will process and respond same data to SF.

We can't let a single microservice to listen to all events as it will be again a single point of failure. Also, we cannot pop an event out of the event bus as its an event bus and not an event queue.

Has anyone faced this and what possible solution can be built around it?

2 Answers 2

4

While I haven't really been into such a design issue, but I do see a way to overcome the situation that you are facing on this part:

The 3rd party microservice listens to it and fetches that file from SF rest endpoint and then processes and updates its data back in SF

If you can break this into different pieces, you should be able to resolve this I assume. However, this is still from a very high level, you will need to definitely look towards parallel processing and deadlock scenarios and how to avoid it.


The approach I can think of is:

  1. Once your microservice (MS1) fetches the event details from SF, you capture the replayId and then store that in a table in your local db or elsewhere.
  2. You make the call to SF only if there does not exist the same replayId in your db
  3. Let's say in the meantime another microservice (MS2) fetches the same replayId, it doesn't make call to SF as it sees the value in the db
  4. In case of failures from MS1 callouts, you just delete the replayId from the db, so that any other microservice again getting that replayId can take care of making the updates.

Another approach I can think here is to utilize a Queue (say using Azure service bus or MuleSoft) along with the one mentioned above. In this approach, you can have services subscribed to the Events in Salesforce publish those events as messages in the queue. Here you will though need to make sure that the replayId being added to the Queue is unique in nature.

Now, you have another service reading from the queue which takes care of calling out to SF based on the replayId. Because you have a Queue implementation, the time you read a message from the Queue, a lock will be placed on the message and will not be available for any other service and thus you can handle any concurrency issues this way.


In summary, you will need to make sure your microservices can communicate with each other to avoid any deadlock or concurrency issues.

4
  • This would work when both microservices have a delay of few microseconds in between before reacting, but if both works at same time then probably it would still cause the issue I mentioned. Now it looks more like concurrency . Commented Nov 5, 2018 at 15:16
  • Let me add some more details as I think it through.
    – Jayant Das
    Commented Nov 5, 2018 at 15:21
  • Thanks, I will have a look in Azure Service Bus, It looks Interesting. Commented Nov 5, 2018 at 15:31
  • Question in this case, is if there was 3 instances running, would all 3 always receive the Event from Salesforce (I assume yes) and if so, any thoughts on the efficiency of having to either build a message queue or uniqueness of processing? Seems like it may just be a good candidate for a single instance which has more power to simplify the whole thing?
    – Doug
    Commented Jul 28, 2019 at 21:12
4

Ultimately, you need some cooperation. You can't have an event bus with multiple independent nodes that can't communicate with each other from each processing every event. It's impossible. At some point, you need a common point of communication. Either the microservices need to chat with each other, or they need to take turns in some coordinated manner, or you need a frontend to delegate the events evenly, or you need a central queue to place the events in, or something else that will ultimately lead to a break from what you're defining as a microservice architecture. The microservices architecture is not suitable for all possible applications. This is one of those applications.

2
  • I kinda have that thought in my mind that I wanted to believe is not true. Thanks for the wise words, I will look at how to make them communicate with each other or see if some already built API for the central queue is there. Commented Nov 5, 2018 at 15:18
  • 3
    @PranayJaiswal You may also want to read on en.wikipedia.org/wiki/Microservices. Microservices are allowed to talk to each other. That's not what defines a microservice. The underlying structure would probably involve shared memory/IPC to keep track of already used replay Id values, but you're still going to have a central storage area somewhere. These microservices do not exist in total isolation.
    – sfdcfox
    Commented Nov 5, 2018 at 15:28

You must log in to answer this question.

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