Replaying events - validating transitions - cqrs

I'm wondering exactly what logic should be contained when applying an event to a state while replaying events using some event sourcing solution.
Specifically, I'm wondering about validation, say I've got entity which can be in one of the following status:
Logged
Active
Close
Cancelled
and the progress needs to be Logged->Active->Close or Logged->Active->Cancelled, we cannot jump from Logged to Close directly for example.
Now, I understand, the validation should be contained in commands: UpdateState would check if the entity current state allows transition to desired one, and would produce appropriate event StatusUpdated which would be persisted into the event store.
Question is, what should I do when replaying it back? Should I just update the status, or should I perform same validation (so that if status transition requirements change it won't be possible to load some previously updated entities unless we add some additional logic), to ensure we won't end up with entities that do not satisfy our current logic?
PS. I think I've got problems grasping it because in my understanding events are essentialy just about 'announcing' something that happened already (and the sender state is already modified) so that interesting parties can react accordingly. And in case of events loading/replaying, you need to alter said state instead of actually 'announce' anything...

You do not need to perform any validation when replaying the event stream.
Commands model things that will be done in the future: You ask the system do to something for you. It's up to the system to decide whether to do it or not, e.g. based on business rules and validation.
Events in contrast model things that have already happened. As in the reality, you can not change the past.
So, this means, when an event gets persisted, it was in consequence of a command which was taken as valid at the point in time when it was processed. Replaying an event stream simply means to have a look at what happened in the past, and you can not change this.
Hence, you do not need to run any validation again.
Moreover, this means that if one day your business logic changes, all the things (business accidents!) that happened in the past still have happened, so they must not change. Hence you are not allowed to use any validation logic, as it may be another one today than when it was when you stored the events.
And again: You can not (and should not) change the past :-)
Example
Supposed you have a way of validating credit card numbers. A customer comes to your shop, pays, you consider his / her card as valid given your current set of rules, and everything is fine.
Then, one day the credit card institute changes the way credit card numbers are calculated, and hence you have another validation algorithm.
When you now play back your past events, the payment had happened, with or without the new validation rules - and you can not change the fact that it had happened! If you wanted to you had to create a new transaction to send money back to the customer. Again, this would result in a new event, not in a changed one from the past.
So, to cut a long story short: Don't validate events against anything. They are valid by definition, as they had happened before.

Any event stream that's been written to the event store should be valid to be played back without introducing any logic in the event handlers. If you needed to change your transitioning process, you'd need to look at doing some sort of conversion, along the lines of this example.
Regarding your last point. Event sourcing is a technique for persisting and restoring the state of an entity using a historical record of ordered events. It just so happens that when you're saving the entity, you can also publish these events for any interested parties to consume.

Related

What are the best practices when working with data from multiple sources in Flutter/Bloc?

The Bloc manual describes the example of a simple Todos app. It works as an example, but I get stuck when trying to make it into a more realistic app. Clearly, a more realistic Todos app needs to keep working when the user temporarily loses network connection, and also needs to occasionally check the server for updates that the user might have added from another device.
So as a basic data model I have:
dataFromServer, which is refreshed every five minutes, and
localData, that describes what changes have been made locally but haven't been synchronized to the server yet.
My current idea is to have three kinds of events:
on<GetTodosFromServer>() which runs every few minutes to check the server for updates and only changes the dataFromServer,
on<TodoAdded>() (and its friends TodoDeleted, TodoChecked, and so on) which get triggered when the user changes the data, and only change the localData, and
on<SyncTodoToServer>() which runs whenever the user changes the todo list, or when network connectivity is restored, and tries to send the changes to the server, retrieves the new value from the server, and then sets the new dataFromServer and localData.
So obviously there's a lot of interaction between these three methods. When a new todo is added after the synchronization to the server starts, but before synchronization is finished, it needs to stay in the local changes object. When GetTodosFromServer and SyncTodoToServer both return server data, they need to find out who has the latest data and keep that. And so on.
Coming from a Redux background, I'm used to having two reducers (one for local data, one for server data) that would only respond to simple actions. E.g. an action { "type": "TodoSuccessfullySyncedToServer", uploadedData: [...], serverResponse: [...] } would be straightforward to parse for both the localData and the dataFromServer reducer. The reducer doesn't contain any of the business logic, it receives actions one by one and all you need to think about inside the reducer is the state before the action, the action itself, and the state after the action. Anything you rely on to handle the action will be in the action itself, not in the context. So different pieces of code that generate those actions can just fire these actions without thinking, knowing that the reducer will handle them correctly.
Bloc on the other hand seems to mix business logic and updating the state. API calls are made within the event handlers, which will emit a value possibly many seconds later. So every time you return from an asynchronous call in an event handler, you need to think about how the state might have changed while that call was happening and the consequences this has on what you're currently doing. Also, an object in the state can be updated by different events that need to coordinate among themselves how to avoid conflicts while doing so.
Is there a best practice on how to avoid the complexity that brings? Is it best practice to split large events into "StartSyncToServer" and "SuccessfullySyncedToServer" events where the second behaves a lot like a Redux reducer? I don't see any of that in the examples, so is there another way this complexity is typically avoided in Bloc? Or is Bloc entirely unopinionated on these things?
I'm not looking for personal opinions here, only if there's something I missed in the Bloc manual (or other authoritative source) about how this was intended to work.

Axon- Replay event for a particular type or for one particular Id

Using Axon framework- I was able to replay the entire event store and re-create the view model. But is it possible to replay event for a particular type or for a particular Id.
Let's say, I have a customer event and I want to replay all the event of a customer with Id= 100. Is it make sense to do a replay for a particular customer or it make more sense to replay for the entire event store always?
Thanks in advance
It is OK to do whatever makes sense for you, for this particular ReadModel.
One reason to re-process only one customer is the speed. If it's a lot faster than a complete rebuild (i.e because you have a lot of customers) and the outcome is the same then do it.
As Constantin points out, this request to replay a specific view makes total sense.
The provided replay process in Axon Framework at this point only provides to trigger a replay for a specific Processing Group allowing you to set the point in time from when you want to replay it.
There are ideas to provide a more fine grained solution to replaying, I'd however be hard pressed to tell you when that'll happen.
Thus replaying just a single view model for, for example speed, will require some custom code.
Let me know if you'd be interested in some pointers on how to do that.
Update
I'd like to state that with more recent versions of Axon Framework is is possible to tell a TrackingEventProcessor to reset itself, thus replay a set of events.
The API for this is the TrackingEventProcessor#resetTokens(TrackingToken), which allows you to reset a Tracking Event Processor from a given point in time.
This still doesn't give you the option to replay a given instance of a Read Model. This would still require some handy work from your part.

EventSourcing inside and outside Bounded Contexts

I'm trying to implement an event sourced system with dddd. Currently I'm struggling how and where my events are crossing the boundaries of the bounded contexts.
Imagine there are two bounded contexts:
Product Management
Logistics System
Product Management has all the knowledge about the products. For simplification it is just "Name". The logistics system also has products, but has no knowledge about their meta data. For them it is mostly only a physical box with an Id. But when somebody scans this product, they want to show the name either. So the ProductManagement BC should inform the Logistics BC, that a product is registered and a name has changed. So I will end up with the events in ProductManagement, raised from inside the ProductAggregate:
ProductManagement.Events.ProductRegistered
ProductManagement.Events.ProductNameChanged
When I got it correctly these are the events which I will save into the event store. And these are also the events which will be published into the message bus. So at the logistics side I will subscribe to these events. So far so good.
The problem now is:
How will I work with this event on the Logistics side? Vaughn Vernon said in a talk, that it is best practice to have an event handler there, which is in the application layer, so it will basically be an application service. He also said, that it would be best to transform it to one or several commands. Do I save all received events on the logistics side again? Do I also save the commands? How can I reproduce my current state if something went wrong? Or how will I know, that it is not the fault of the processing in the receiving Bounded Context, but rather a wrong event. What will I do if my transformed commands getting rejected?
I know that there are no calculations or changes in aggregates on logistics side. But I think this doesn't really matter for my questions.
Couple of things here.
First, you do not have to import the Logistics BC about name changes. You can get this information from the PM BC when needed, from the client. This is usually done by some sort of composite UI. The UI composition can be done on the client or on the (web) server. You may want to check the article The secret of better UI composition by Mauro Servienti, describing this.
But in general, this usually works like this:
domain event -> pub/sub -> message consumer -> command -> domain command handler
So,
you publish your domain event to the bus, from the PM BC
there is an event handler for this event in the Logistics
the event handler may do some checks, and send the RegisterProduct command to the same BC
the command is handled as usual and new Product aggregate is created in the Logistics
It works like this not only in event-sourced system but in any system with multiple services, using event-driven architecture.
For the use case you describe, you just need some properties of the product to be used by the logistics system. The logistics system therefor could keep a local cache of the product information it needs by subscribing to the events you describe - this could be a simple in-memory cache. They don't need converting into commands or anything like that as you're dealing with the read model I.e. A view. Just have a simple event handler handle the event and update some state somewhere - no need to event source it on the read side. When the logistics system needs the name of the product, it just gets it from its local cache. You haven't broken the autonomy of the two contexts as Product Management is still the source of truth.
If you ever need to rebuild the state you can just wipe the cache and replay all events through your handlers. But remember the Product Management context owns these events so they should only be saved there, not in the Logistics context - you would need a way of republishing them if you ever wanted to rebuild state
By the way this series of blog posts describes this exact use case:
https://www.tigerteam.dk/2014/micro-services-its-not-only-the-size-that-matters-its-also-how-you-use-them-part-1/
(At part 5 if I recall correctly)
Alternatively you can do some sort of UI composition where the name is taken from the Product Management context and the other details from the Logistics context (also discussed in the above blog posts)
[...] He also said, that it would be best to transform it to one or several commands. Do I save all received events on the logistics side again? Do I also save the commands?
First, you have to ask the domain experts if that event will cause a side effect that impact the LS context. Only in this case, you have to subscribe to this event and send the related command to the LS Aggregate that will change and commit its state or, if you choose to event-source this aggregate too, another event.
How can I reproduce my current state if something went wrong? Or how will I know, that it is not the fault of the processing in the receiving Bounded Context, but rather a wrong event? What will I do if my transformed commands getting rejected?
An event is a representation of something happened, so it can't be "wrong". Anyway, commands triggered by an event can fail. Which type of failure are you talking about? Technical or domain specific? In the first case, the source event will stay in the bus for a future retry (maybe after some bug fix). In the second case, if the PM aggregate needs to be informed about the result, the LS Aggregate should emit an appropriate event which, in turn, will be handled by the PM aggregate.

What triggers UI refresh in CQRS client app?

I am attempting to learn and apply the CQRS design approach (pattern and architecture) to a new project but seem to be missing a key piece.
My client application executes a query and retrieves a list of light-weight, read-only DTOs from the read model. The user selects an item and clicks a button to initiate some action. The action is performed by creating and sending the corresponding command object to the write model (where the command handler carries out the action, updates the data store, etc.) At some point, however, I need to update the UI to reflect changes to the state of the application resulting from the action.
How does the UI know when it is time to refresh the original list?
Additional Info
I have noticed that most articles/blogs discussing CQRS use MVC client apps in their examples. I am working on a Silverlight client right now and am beginning to wonder if the pattern simply doesn't work in that case.
Follow-Up Question
After thinking more about Bartlomiej's response and subsequent discussion, I am wondering about error handling in CQRS. Given that commands are basically fire-and-forget asynchronous operations, how do we report an error condition to the UI?
I see 'refreshing the UI' to take one of two forms:
The operation succeeds, data has changed and the UI should be updated to reflect these changes
The operation fails, data has not changed but the user should be notified of the failure and potential corrective actions.
Even with a Post-Redirect-Get pattern in an MVC, you can't really Redirect until you know the outcome of the operation. None of the examples I've seen thus far address these real-world concerns.
I've been struggling with similar issues for a WPF client. The re-query trigger for any data is dependent on the data your updating, commands tend to fall into categories:
The command is a true fire and forget method, it informs the back-end of a state change but this change does not need to be reflected in the UI, or the change simply isn't important to the UI.
The command will alter the result of a single query
The command will alter the result of multiple queries, usually (in my domain at least) in a cascading fashion, that is, changing the state of a single "high level" piece of data will likely affect many "low level" caches.
My first trigger is the page load, very few items are exempt from this as most pages must assume data has been updated since it was last visited. Though some systems may be able to escape with only updating financial and other critical data in this way.
For short commands I also update data when 'success' is returned from a command. Though this is mostly laziness as IMHO all CQRS commands should be fired asynchronously. It's still an option I couldn't live without but one you may have to if your implementation expects high latency between command and query.
One pattern I'm starting to make use of is the mediator (most MVVM frameworks come with one). When I fire a command, I also fire a message to the mediator specifying which command was launched. Each Cache (A view model property Retriever<T>) listens for commands which affect it and then updates appropriately. I try to minimise the number of messages while still minimising the number of caches that update unnecessary from a single message so I'll (hopefully) eventually end up with a shortlist of update reasons, with each 'reason' updating a list of caches.
Another approach is simple honesty, I find that by exposing graphically how the system updates itself makes users more willing to be patient with it. On firing a command show some UI indicating you're waiting for the successful response, on error you could offer to retry / show the error, on success you start the update of the relevant fields. Baring in mind that this command could have been fired from another terminal (of which you have no knowledge) so data will need to timeout eventually to avoid missing state changes invoked by other machines also.
Noting the irony that the only efficient method of updating cache's and values on a client is to un-separate the commands and queries again, be it through hardcoding or something like a hashmap.
My two cents.
I think MVVM actually fits into CQRS quite well. The ViewModel simply becomes an observable ReadModel.
1 - You initialize your ViewModel state via a query on the ReadModel.
2 - Changes on your ViewModel are automatically reflected on any Views that are bound to it.
3 - Certain changes on your ViewModel trigger a command to propegate to a message queue, an object responsible for sending those commands to the server takes those messages off the queue and sends them to the WriteModel.
4 - Clients should be well formed, meaning the ViewModel should have performed appropriate validation before it ever triggered the command. Once the command has been triggered, any event notifications can be published onto an event bus for the client to communicate changes to other ViewModels or components in the system interested in those changes. These events should carry the relevant information necessary. Typically, this means that other view models usually don't have to re-query the read model as a result of the change unless they are dependent on other data that needs to be retrieved.
5 - There is an object that connects to the message bus on the server for real-time push notifications when other clients make changes that this client is interested in knowing about, falling back to long-polling if necessary. It propagates those to the internal message bus that ties the components on the client together.
6 - The last part to handle is the fact that clients can be occasionally connected, which should be the only reason a command fails (they don't have internet access at the moment), which is when the client should be notified of problems.
In my ASP.NET MVC 3 I use 2 techniques depending on use case:
already well-known Post-Redirect-Get pattern which fits nicely with CQRS. Your MVC action that triggers the command returns a redirection to action that performs a query.
in some cases, like real-time updates of other clients, I rely on domain events/messages. I create an event handler that uses singlarR to push changes to all connected and interested clients.
There are two major ways you can take as far as I know :
1) design your UI , so that the user does not see its changes right away. Like for instance a message to tell him his action is a success, and offering him different choices to continue his work. this should buy you enough time to have updated your readmodel.
2) more complex, but you might keep the information you have send to the server and shows them in the interface.
The most important I guess, educate your user if you can so that they know why the data is not here... yet!
I am thinking about it only now, but these are for sync command handling, not async, in async things go really harder on the brain...the client interface becomes an event eater too..

Saga , Commands , events & ReadModel

I am currently writing my first saga and I am a bit puzzled with the read model. Let's explain it with an example :
I have three bounded context : programming, contractor and control. Each of them has its specific read model.
worflow :
programming send an event "JobScheduled"
Saga receives this event and tell contractor to "schedule the Work".
When done the Contractor send an event "JobDone".
The Saga receives this event and tell Control to "Start Control Period".
Everything turns out to be fine here. We are on the write side so we are passing vital information for the process to go on.
My question comes with unnecessary information. Let's say that the event "JobScheduled"
has a note field : "test note", and before this job is done this field is changed to "test note important". This change is of no importance to the workflow as described, but it is important that the contractor might see the change in the field when looking at the read model of the contractor bounded context.
Am I to give to the saga the event NoteChanged and process it or should I create a projection which directly listens to this event in my contractor bounded context?
To give it to the saga looks to me like unnecessary work because I am only updating readmodel here there is no domain involved in the change.
On the other hand, making a direct coupling between the two bounded context removes one of the assets of sagas which is the possibilty of modifying the interactions the bounded context have between each other in the workflow.
Thanks for your reading,
If changing the note is important, it should be modelled explicitly. This can be accomplished by introducing an Event just like you already did.
If said Event has any relevancy to the process, it can be handled by a Saga. If it only needs to be represented in different Read Models, then just handling it in their respective projections should be fine.
One context may very well listen to and handle the events of another one, even across application boundaries. At least this is how cross-context integration should work in an event centric architecture.
Personally I would send a command "Change note", because I see it like an information that have to be saved in the event stream of your aggregate. Than if your saga don't "feel" to tell anyone about this command, or simply give the information to an handler that quietly update your read model I guess is fine.