Subscription Queries - inconsistency and lag when we use Subscription query

Hello Team,

We are trying to implement Subscription Queries to get updated values from the read store but still getting previous state of the result returned by the Queries.

App: Payment integration for ecommerce website.

Tech stack: Spring Boot, Postgres , AXON Framework

Deployment Env: Google Cloud Platform (Kubernetes)

Implementation:

Request Call 1: Restcontroller fires a command ‘CreatePayment’ to initialize the PaymentContext, in aggregate commandhandler method fires an event which will update our ReadStore database. As a response it sends a unique PaymentContextID.

In the same rest call we are trying to use Subscription query to read the data from read store but it returns no result.

**Reason: Event fired by CommandHandler method is not yet processed by the @**EventSourceHandler . Once response is sent back to caller then @EventSourceHandler method gets executed.

Request Call2: Get all the PaymentOptions available for the market.

In this call we initialize the payment session and we change the aggregate state to ‘PaymentSession_initialized’but before that it verifies whether PaymentAggregate is in valid state or not. So in normal scenario valid state is ‘PaymentContextCreated’

To do this validation we read the data from read store using Subscription query but sometime it returns ‘Null’.

Out of 100 times 80% we received the data but for 20% time it returns null.

Note: UI makes rest call1 and rest call2 within a 1-2 seconds.

Request Call3: Get Payment Status:

When user calls ‘GetPaymentStatus’ after making first two request call, the correct PaymentStatus should be ‘Payment_Session_Initialized’ and again 20% times it returns ‘PaymentContextCreated’ status. We use Subscription query to read the data from read store (a Different table which is kind of Snapshot of out Aggregate).

We see inconsistency and lag here when we use Subscription query.

@EventSourceHandler method?

Thanks

Aniwesh

Please replace @EventSourceHandler to @EventHandler as our @EventHandler methods are not part of Aggregate class. Read Store get updated on @EventHandler methods (When aggregate state is changed).

Hi Aniwesh,

First and foremost, I would suggest that you embrace the fact that you are in an asynchronous world when dealing with the messaging approach of Axon.
Thus, if you are going for CQRS, you should segregate dispatching the command from retrieving the data through a query.
That’s what CQRS as “Command-Query Responsibility Segregation” stands for after all.

However, there might be scenarios where this isn’t an option.
To that end, combining the Subscription Query to retrieve data with dispatching a command to spoof synchronous operation, is a reasonable approach.
This repository by Frans van Buul shows just how you could perform such a spoof.

In short, what you should do in your rest controller, is first perform the subscription query and only use the updates from the result.
Secondly, you dispatch the command that will trigger the eventual update of the Query Model you have done a subscription query on.
Lastly, once you have the result, you break off the subscription query.

Then for the other question you have posted here:
Another Question: Is it a good or bad practice to Fire a command from @EventSourceHandler method?
The Event Sourcing Handler’s purpose is to update the state of the Command Model / Aggregate.
Sending a command is not updating the state, but it is performing subsequent operations.
As you are mixing concerns in doing so, I would not suggest to dispatch commands in event sourcing handlers.

Hope this helps Aniwesh!

Cheers,
Steven

Thanks Steven for your reply and sharing example (GIT repo) dispatching a command to spoof synchronous operation. :slight_smile:

Thanks
Aniwesh