Same event handler for writing to a viewtable and for saga with execution order

Consider 2 microservices, Product and User. User can only browse two Products per day.
The Gateway redirects URL requests to the Product microservice if the limit for viewing is not hit. But those two recently viewed products can be viewed any number of time within that day.

I’m keeping Recently Viewed Products in another aggregate with a viewtable. Every time a product is requested, Create_Recently_Viewed_Product command is executed and rvp_created event is generated.

To solve this problem, every time a new recently viewed product for a certain user is created, I need to read the number of products viewed from the viewtable and send it to the Users microservice which restricts the Gateway from the overlimit requests.
So, I’m handling rvp_created event, writing to the Recently viewed by user to the viewtable. At the same time I’m trying to handle the same event in the saga with execution order 2. This saga’s purpose is to read number of Recently viewed by user and send it to the User microservice. If number of views is more than 2, User microservice will restrict the Gateway.

The problem is that even thought the execution order of the event handlers are correct, when Saga tries to read the viewtable, the Recently viewed is still not written the last entry.

I understand that both events are executing simultaneously, though I’m trying to use execution order.
What is your suggestion? Should I generate custom event after writing to the recently viewed viewtable?


If at all possible, I’d loseen the requirement a little bit.
When you write Event Handling components like your projection class and the saga, you should ideally regard them as entirely separate components.

Doing this makes the messages they handle their boundary, not caring about other components directly.
Thus, if your example can deal with some level of eventual consistency, that would be ideal.
It would mean sometimes users get to see a product that in the ideal world isn’t shown anymore, of course.

Axon does enable a way to combine Event Handling Components and impose an ordering.
Achieving this between Event Handling Components is by ensuring they belong to the same processing group.
From there, you can use Spring’s @Order annotation to define the invocation order of the event handlers by the Event Processor.

However, this does not extend to Sagas, as those are separate Processing Groups by design.
So, if the requirement you share is a hard one, potentially, it is best to introduce another layer of events just for that orchestration.