Reputation: 2268
I'm currently using SubscribingEvent processor in Axon. Using this, everything is executed in single thread (since I want to execute command and apply events to projection in single thread) making sure either everything is persisted to DB or everything is rolled back.
What happens in case we use TrackingEvent processor, in case that command is successfully executed in Aggregate and that events that Aggregate emits are preserved to DB, but application fails just before Projections are done (that means not saved to DB)? Will application after restart continue projecting this events?
In my case I'm doing projection on REST call, so I guess it makes sense for me to use SubscribingEvent processor (so either all is OK, or nothing is). In case I use TrackingEvent processor, and app crashes between save and projection - I would have inconsistent state. And even if projection is restarted on next boot (as I assume is), client would send same command again (thinking it is failed), but what would happen in aggregate if it receives same command 2nd time?
Upvotes: 2
Views: 322
Reputation: 7275
let me try to give you some insights into this!
What happens in case we use TrackingEvent processor, in case that command is successfully executed in Aggregate and that events that Aggregate emits are preserved to DB, but application fails just before Projections are done (that means not saved to DB)?
The TrackingEventProcessor
in Axon keeps track of which events it has handled, through the means of the TrackingToken
. A Tracking Processor will only update the TrackingToken
after all the Event Handling Components (e.g. the components updating your projections) have been called.
Thus, on a restart at that point in time,the Tracking Processor will handle the event again. In doing so it tries to be up to date with the entirety of your event stream.
In case I use TrackingEvent processor, and app crashes between save and projection - I would have inconsistent state.
This depends on how you've implemented your application. It sounds like everything is quite tightly coupled and in doing so not embracing the fact you'll have to deal with eventual consistency. I know it's easier said than done, but having your front-end not expect an immediate response when you issue a command will simplify the system in the end. Then again, this highly depends on whether you can influence the UI's perspective on doing things; not sure whether that's an option in your situation.
And even if projection is restarted on next boot (as I assume is), client would send same command again (thinking it is failed), but what would happen in aggregate if it receives same command 2nd time?
This fully depends on how you've implemented your Aggregate. The Aggregate should make the decision whether a command can be executed or not. If part of that decision making is ensure that the previous command was not identical to the current operation, then you'll need to take that into account in the @CommandHandler
annotated functions.
I hope this gives you some insights Bojan and do not hesitate to answer more questions to get a grip on this part of Axon.
Upvotes: 2