2

I have started implementing microservices in an Event-Driven Architecture. Therefore some of my services are publishing events and listening to some other events. It is very straightforward to implement a listener when an action depends on one single event, for example;

ORDER SERVICE 
  1. Publishes `ORDER_INTENT_EVENT` then
  2. Listens for `CREDIT_AVAILABLE_EVENT` then
  3. Finishes the `Order`

CREDIT SERVICE
  1. Listens for `ORDER_INTENT_EVENT` then
  2. Verifies if the client has credit then locks the amount and
  3. Publishes `CREDIT_AVAILABLE_EVENT`

The problem arises when OrderService has to wait for more than one event, for example;

ORDER SERVICE 
  1. Publishes `ORDER_INTENT_EVENT` then
  2. Listens for `CREDIT_AVAILABLE_EVENT` 
             and `INVENTORY_AVAILABLE_EVENT` then <--- Problem here

  3. Finishes the `Order`

CREDIT SERVICE
  1. Listens for `ORDER_INTENT_EVENT` then
  2. Verifies if the client has credit then locks the amount and
  3. Publishes `CREDIT_AVAILABLE_EVENT`

INVENTORY SERVICE
  1. Listens for `ORDER_INTENT_EVENT` then
  2. Verifies if inventory has items then locks the items and
  3. Publishes `INVENTORY_AVAILABLE_EVENT`

The thing is; I am pooling both queues CREDIT_AVAILABLE_QUEUE and INVENTORY_AVAILABLE_QUEUE, and both events has to be present so I can finish an order. How can I coordinate so that OrderService sees both events as only one?

I can implement it at the application level, for example; if one event arises I save it to the database and check if there is the other corresponding event to same order, if so I proceed with finishing the order, if not I do nothing then when the other event arrives I will have both of them so I am able to finish the order. The problem with this approach is that there is a minimal chance of receiving both events at the same time generating race conditions.

What is the suggested pattern for this kind of scenario?

PS.: I found this similar question but one answer suggests .net related tools and the other points to a third party service. I am interested in a pattern/code solution.

Renato Gama
  • 16,431
  • 12
  • 58
  • 92
  • This is known as Complex Event Processing (CEP) and there are many frameworks in open source world to solve this type of problems. – skjagini Jul 20 '18 at 03:57
  • 1
    Yes, @skjagini the thing is that I was looking for a pattern to handle this scenario and implement it my self. I actually already have an answer. Will post it as soon as I understand things more clearly. – Renato Gama Jul 20 '18 at 07:54
  • 1
    @RenatoGama What was your solution? – BenV May 12 '21 at 16:02

1 Answers1

0

Any time you have multiple input sources to a particular piece of state, you have the potential for a race condition. This is why we have locks. You MUST use a lock of some sort to handle the race condition.

This may be implemented at the database layer, or using a locking library, or a shared piece of memory (please use a locking library unless you have way more understanding of memory / CPU architecture than this posting implies).

Most languages implement some form of mutex locking to allow this problem to be solved. If you are using multiple processes / machines / etc, you will need some form of external mutex locking (often implemented by your database provider). If you lack this, there are distributed lock systems that also can be used.

Rob Conklin
  • 8,806
  • 1
  • 19
  • 23