Hello!
I've recently been experimenting with architectures that use CQRS / Cluster Sharding / Event Sourcing / DDD, and I have some beginner questions.
1) What is the best way to handle changing the structure of "events" as business requirements (or refactorings) change over time?
As a brief example:
// v1
case class ChangeName(id: String, first:String) extends Cmd
case class NameChanged(id: String, first: String) extends Evt
// v2
// now biz req. changes and we want to be able to change both first and last name
// i can freely change the 'Cmd' because we don't persist it, however if I change the 'Evt'
// i will get 'RecoveryFailure was caused by: java.io.InvalidClassException' during recoveries
case class ChangeName(id: String, first:String, last: String) extends Cmd
case class NameChanged(id: String, first: String, last: String) extends Evt
It seems I could always just maintain 2 different events, e.g. NameChangedV1, and NameChangedV2, but that doesn't seem maintainable in the long run.
Another approach I thought of is to save a snapshot before introducing any breaking changes to an "Event" interface before bringing down the app for upgrading. This seems hard - is it even possible with the 'ClusterSharding' extension to send a message (e.g. Snap) to all of its known id's in the system?
How does changing events affect the "read" side of things in CQRS?
============
2) When a node crashes, how can I make sure the "entry" gets restarted and completes processing when the node is brought back up?
Here's a very brief example that may help clarify what I'm asking:
// sent in the beginning of the flow from a front-end
case class ProcessMessage(id: String, message: Message) extends Cmd
case class MessageToBeProcessed(id: String, message: Message) extends Evt
// sent at the end of the flow from another processor actor
case class MessageProcessed(id: String, message: Message) extends Cmd
case class MessageComplete(id: String, message: Message) extends Evt
Let's say the node crashes right after I persist the event 'MessageToBeProcessed' and before I send it to a processor actor to complete processing. Will the 'ClusterSharding' extension re-activate this entry on another available node right away, or will it wait until that entry receives another "Cmd"? If it doesn't re-activate, is there a recommended approach to solve this?
Thanks!
-Chris