Akka CQRS / Cluster Sharding - Change management of "Events" and other questions

103 views
Skip to first unread message

Chris Ridmann

unread,
Apr 13, 2015, 9:54:24 AM4/13/15
to akka...@googlegroups.com
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

Greg Young

unread,
Apr 13, 2015, 1:54:59 PM4/13/15
to akka...@googlegroups.com
For 1 use weak serialization (say json)

Richard Rodseth

unread,
Apr 13, 2015, 2:29:17 PM4/13/15
to akka...@googlegroups.com
My favourite topic


Jay Kreps recently strongly endorsed Avro for use with Kafka.


--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Greg Young

unread,
Apr 13, 2015, 2:35:05 PM4/13/15
to akka...@googlegroups.com
Yep weak/hybrid schema all the way.

So long as adding a field doesn't break downstream consumers then you
are #@$@ed with schema (think binary serializer)
> You received this message because you are subscribed to a topic in the
> Google Groups "Akka User List" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/akka-user/gHI8sR7Lrjs/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> akka-user+...@googlegroups.com.
> To post to this group, send email to akka...@googlegroups.com.
> Visit this group at http://groups.google.com/group/akka-user.
> For more options, visit https://groups.google.com/d/optout.



--
Studying for the Turing test

Chris Ridmann

unread,
Apr 15, 2015, 7:49:43 AM4/15/15
to akka...@googlegroups.com
Thanks for the help guys!  I figured I stumbled onto a big topic here.   :)

@Richard - I haven't used Scala Pickling, though I do have some experience with scodec for binary serialization.  One problem I have with binary serialization with akka-persistence is it makes it makes it harder to debug systems just from querying the database.  This seems to be an issue with some plugins in the ecosystem - thankfully the one I'm using just provided support for a pluggable way of handling serialization for the persistence API.  Avro looks interesting - I'll have to follow that one a bit longer.  I also recently discovered https://github.com/mandubian/scaledn but haven't used it yet.

I think I'm going to go the json-serialization route as my team already has a lot of experience using the play-json formatters/reads/writes so it would flow quite naturally.  I also really like the idea of storing events in the DB in a human readable format.

As per 2), I'm still a bit confused on the scenario if the system crashes after the command is persisted but before the event callback is fired (or right in the middle of the callback).  This seems like it would be a relatively common scenario, and the suggested event-sourcing approaches recommend not to perform side effects while recovering state.

-Chris
Reply all
Reply to author
Forward
0 new messages