Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to wait for the results or exceptions of a Saga?

Tags:

axon

Say I have a Saga that does money transfer in a few milliseconds. I have REST controller which invokes the command that triggers the Saga. How can I wait for the end of the Saga to check the results or exception to have my controller return as a response? If it were simply a lone command that doesn't trigger a Saga, I could use a command gateway and a callback that will notify me of success or failure.

UPDATE:

I was able to have my controller return a response after Saga ends by:

1) My controller method returns a DeferredResult which I save into a map

2) My controller has an event handler which listens for an end event, retrieves the DeferredResult from the map, and sets the result

Is there a better way to go about this?

like image 600
sofiaguyang Avatar asked Mar 10 '23 10:03

sofiaguyang


1 Answers

Axon is designed to decouple different components. Some components handle commands and produce events, other consume events and update a query model, or in the case of a Saga, produce commands again.

Preferably, user interfaces should be designed to also work in this 'eventually consistent' way. When sending a command, the return value just indicates that the command was handled successfully, not that all the side-effects have been executed.

The reason is simple when using an exaggerated example: what if 100 components are interested in an Event produced as a result of a command. Do you want your command handler to block until all these 100 components have been updated? That would cause dramatic (technical) coupling between these components with a huge impact on scalability.

Given that background, you probably still want to update a UI based on changes in read models. If yo expect a certain side-effect to happen any time soon, using DeferredResult or CompletableFuture is a very elegant way to go about. It's basically a style of query where you say: 'let me know when ...', as opposed to 'give me your current state'. Alternatively, you can also push updates to consumers in real-time. We have implemented this in several projects based on Stomp (with Spring Websockets).

Don't forget to eventually clean deferred results from your map in case they have timed out (see DeferredResult.onTimeout(). It would be a pity if your machine crashed because of excessive memory consumption.

like image 193
Allard Avatar answered Mar 11 '23 23:03

Allard